summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-12 19:57:02 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-12 19:57:02 +0000
commit8ef38186faea3d9b5e6f0f1242f668cb7e7a3d52 (patch)
tree9253f150814c99167239f7c2cc850cdd9d92c003
parentf481c39c015a71a6747d8e0f4f923fabe1086ffc (diff)
downloadrtems-8ef38186faea3d9b5e6f0f1242f668cb7e7a3d52.tar.bz2
Patch from John Cotton <john.cotton@nrc.ca>, Charles-Antoine Gauthier
<charles.gauthier@iit.nrc.ca>, and Darlene A. Stewart <Darlene.Stewart@nrc.ca> to add support for a number of very significant things: + BSPs for many variations on the Motorola MBX8xx board series + Cache Manager including initial support for m68040 and PowerPC + Rework of mpc8xx libcpu code so all mpc8xx CPUs now use same code base. + Rework of eth_comm BSP to utiltize above. John reports this works on the 821 and 860
-rw-r--r--aclocal/bsp-alias.m41
-rw-r--r--aclocal/check-bsps.m41
-rw-r--r--c/src/exec/libcsupport/include/sys/termios.h1
-rw-r--r--c/src/exec/libcsupport/src/malloc.c22
-rw-r--r--c/src/exec/libcsupport/src/termios.c8
-rw-r--r--c/src/exec/posix/src/waitpid.c2
-rw-r--r--c/src/exec/rtems/include/rtems/rtems/Makefile.am6
-rw-r--r--c/src/exec/rtems/include/rtems/rtems/cache.h140
-rw-r--r--c/src/exec/rtems/src/Makefile.am2
-rw-r--r--c/src/exec/rtems/src/cache.c252
-rw-r--r--c/src/exec/score/cpu/i386/rtems/score/i386.h136
-rw-r--r--c/src/exec/score/cpu/m68k/rtems/score/m68k.h239
-rw-r--r--c/src/exec/score/cpu/powerpc/asm.h10
-rw-r--r--c/src/exec/score/cpu/powerpc/old_exception_processing/Makefile.am2
-rw-r--r--c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.c7
-rw-r--r--c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.h9
-rw-r--r--c/src/exec/score/cpu/powerpc/rtems/score/ppc.h157
-rw-r--r--c/src/exec/score/cpu/powerpc/shared/asm.h10
-rw-r--r--c/src/exec/score/cpu/powerpc/shared/ppc.h157
-rw-r--r--c/src/exec/score/include/rtems/score/object.h34
-rw-r--r--c/src/exec/score/include/rtems/score/thread.h17
-rw-r--r--c/src/exec/score/src/Makefile.am19
-rw-r--r--c/src/exec/score/src/objectlocaliterate.c77
-rw-r--r--c/src/exec/score/src/threadlocaliterate.c77
-rw-r--r--c/src/lib/include/sys/termios.h1
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/startup/bspstart.c3
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/README72
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/bsp_specs2
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/include/bsp.h26
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/network/network.c85
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/startup/linkcmds4
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/startup/page_table.c50
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c7
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/console/console.c86
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h4
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/network/network.c377
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c19
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/startup/cpuinit.c44
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds4
-rw-r--r--c/src/lib/libbsp/powerpc/eth_comm/startup/mmutlbtab.c45
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/Makefile.am17
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/README372
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/bsp_specs26
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/configure.in36
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/console/Makefile.am32
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/console/console.c484
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/include/Makefile.am23
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/include/bsp.h121
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/include/coverhd.h366
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/network/Makefile.am36
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/network/network.c1702
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am42
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c193
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache202
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c535
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds259
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c132
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c44
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S383
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/times-mbx821191
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/times-mbx860191
-rw-r--r--c/src/lib/libbsp/powerpc/mbx8xx/wrapup/Makefile.am40
-rw-r--r--c/src/lib/libbsp/powerpc/support/old_exception_processing/Makefile.am2
-rw-r--r--c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.c7
-rw-r--r--c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.h9
-rw-r--r--c/src/lib/libc/malloc.c22
-rw-r--r--c/src/lib/libc/termios.c8
-rw-r--r--c/src/lib/libcpu/i386/cpu.h47
-rw-r--r--c/src/lib/libcpu/i386/page.c30
-rw-r--r--c/src/lib/libcpu/powerpc/Makefile.am7
-rw-r--r--c/src/lib/libcpu/powerpc/configure.in34
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am10
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/README19
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/clock/Makefile.am30
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c188
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/console-generic/Makefile.am30
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c1036
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am38
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c34
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c89
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/include/Makefile.am28
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/include/console.h37
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/include/cpm.h38
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/include/mmu.h49
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h1399
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am30
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c120
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/timer/Makefile.am30
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/timer/timer.c104
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/vectors/Makefile.am33
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/vectors/README23
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/vectors/align_h.S430
-rw-r--r--c/src/lib/libcpu/powerpc/mpc8xx/vectors/vectors.S1300
-rw-r--r--c/src/lib/libcpu/powerpc/old-exceptions/cpu.c7
-rw-r--r--c/src/lib/libcpu/powerpc/old_exception_processing/Makefile.am2
-rw-r--r--c/src/lib/libcpu/powerpc/old_exception_processing/cpu.c7
-rw-r--r--c/src/lib/libcpu/powerpc/old_exception_processing/cpu.h9
-rw-r--r--c/src/lib/libcpu/powerpc/shared/cpu.h27
-rw-r--r--c/src/make/compilers/gcc-target-default.cfg14
-rw-r--r--c/src/tests/configure.in1
-rw-r--r--c/src/tests/libtests/termios/init.c5
-rw-r--r--c/src/tests/samples/cdtest/system.h3
-rw-r--r--c/src/tests/sptests/Makefile.am2
-rw-r--r--c/src/tests/sptests/configure.in1
-rw-r--r--cpukit/libcsupport/include/sys/termios.h1
-rw-r--r--cpukit/libcsupport/src/malloc.c22
-rw-r--r--cpukit/libcsupport/src/termios.c8
-rw-r--r--cpukit/posix/src/waitpid.c2
-rw-r--r--cpukit/rtems/include/rtems/rtems/cache.h140
-rw-r--r--cpukit/rtems/src/Makefile.am2
-rw-r--r--cpukit/score/cpu/i386/rtems/score/i386.h136
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/m68k.h239
-rw-r--r--cpukit/score/cpu/powerpc/asm.h10
-rw-r--r--cpukit/score/cpu/powerpc/rtems/asm.h10
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/ppc.h157
-rw-r--r--cpukit/score/include/rtems/score/object.h34
-rw-r--r--cpukit/score/include/rtems/score/thread.h17
-rw-r--r--cpukit/score/src/Makefile.am19
-rw-r--r--make/compilers/gcc-target-default.cfg14
-rw-r--r--make/custom/eth_comm.cfg33
-rw-r--r--make/custom/mvme167.cfg5
-rw-r--r--make/leaf.cfg4
-rw-r--r--testsuites/libtests/termios/init.c5
-rw-r--r--testsuites/samples/cdtest/system.h3
-rw-r--r--testsuites/sptests/Makefile.am2
125 files changed, 13343 insertions, 501 deletions
diff --git a/aclocal/bsp-alias.m4 b/aclocal/bsp-alias.m4
index 19a199c4af..e574ef44a2 100644
--- a/aclocal/bsp-alias.m4
+++ b/aclocal/bsp-alias.m4
@@ -14,6 +14,7 @@ AC_DEFUN(RTEMS_BSP_ALIAS,
gen68360_040) $2=gen68360 ;; # m68k - 68360 in companion mode
p4600) $2=p4000 ;; # mips64orion - p4000 board w/IDT 4600
p4650) $2=p4000 ;; # mips64orion - p4000 board w/IDT 4650
+ mbx8*) $2=mbx8xx ;; # MBX821/MBX860 board
pc486) $2=pc386 ;; # i386 - PC with i486DX
pc586) $2=pc386 ;; # i386 - PC with Pentium
pc686) $2=pc386 ;; # i386 - PC with PentiumPro
diff --git a/aclocal/check-bsps.m4 b/aclocal/check-bsps.m4
index fb208ab023..9e5ed7a6fe 100644
--- a/aclocal/check-bsps.m4
+++ b/aclocal/check-bsps.m4
@@ -23,6 +23,7 @@ AC_MSG_CHECKING([for bsps])
gen68360) rtems_bsp="$rtems_bsp gen68360 gen68360_040";;
p4000) rtems_bsp="$rtems_bsp p4600 p4650";;
mvme162) rtems_bsp="$rtems_bsp mvme162 mvme162lx";;
+ mbx8xx) rtems_bsp="$rtems_bsp mbx821_001 mbx860_002";;
motorola_powerpc) rtems_bsp="$rtems_bsp mvme2307 mcp750";;
pc386) rtems_bsp="$rtems_bsp pc386 pc486 pc586 pc686";;
*) $1="[$]$1 $file";;
diff --git a/c/src/exec/libcsupport/include/sys/termios.h b/c/src/exec/libcsupport/include/sys/termios.h
index 7cc28d7d38..199bb2aef2 100644
--- a/c/src/exec/libcsupport/include/sys/termios.h
+++ b/c/src/exec/libcsupport/include/sys/termios.h
@@ -181,6 +181,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, struct termios *);
+int tcdrain(int);
pid_t tcgetprgrp(int);
int tcsetprgrp(int, pid_t);
int tcsendbreak(int, int);
diff --git a/c/src/exec/libcsupport/src/malloc.c b/c/src/exec/libcsupport/src/malloc.c
index 08660d75cc..dc6824891a 100644
--- a/c/src/exec/libcsupport/src/malloc.c
+++ b/c/src/exec/libcsupport/src/malloc.c
@@ -418,5 +418,27 @@ void _free_r(
{
free( ptr );
}
+
+
+/*
+ * rtems_cache_aligned_malloc
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to allocate storage that spans an
+ * integral number of cache blocks.
+ */
+RTEMS_INLINE_ROUTINE void * rtems_cache_aligned_malloc (
+ size_t nbytes
+)
+{
+ /*
+ * Arrange to have the user storage start on the first cache
+ * block beyond the header.
+ */
+ return (void *) ((((unsigned long) malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ + _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
+}
+
#endif
diff --git a/c/src/exec/libcsupport/src/termios.c b/c/src/exec/libcsupport/src/termios.c
index 7883e94b63..5052502e76 100644
--- a/c/src/exec/libcsupport/src/termios.c
+++ b/c/src/exec/libcsupport/src/termios.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
+#include <sys/filio.h>
/*
* FreeBSD does not support a full POSIX termios so we have to help it out
@@ -243,7 +244,7 @@ rtems_termios_open (
/*
* Set default parameters
*/
- tty->termios.c_iflag = BRKINT | ICRNL | IMAXBEL;
+ tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
tty->termios.c_oflag = OPOST | ONLCR | XTABS;
tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
@@ -474,6 +475,11 @@ rtems_termios_ioctl (void *arg)
case RTEMS_IO_TCDRAIN:
drainOutput (tty);
break;
+
+ case FIONREAD:
+ /* Half guess that this is the right operation */
+ *(int *)args->buffer = tty->ccount - tty->cindex;
+ break;
}
rtems_semaphore_release (tty->osem);
args->ioctl_return = sc;
diff --git a/c/src/exec/posix/src/waitpid.c b/c/src/exec/posix/src/waitpid.c
index d52177961d..e367e87074 100644
--- a/c/src/exec/posix/src/waitpid.c
+++ b/c/src/exec/posix/src/waitpid.c
@@ -1,5 +1,5 @@
/*
- * wait() - POSIX 1003.1b 3.2.1
+ * waitpid() - POSIX 1003.1 3.2.1
*
* $Id$
*/
diff --git a/c/src/exec/rtems/include/rtems/rtems/Makefile.am b/c/src/exec/rtems/include/rtems/rtems/Makefile.am
index f9c8d82fef..af16908428 100644
--- a/c/src/exec/rtems/include/rtems/rtems/Makefile.am
+++ b/c/src/exec/rtems/include/rtems/rtems/Makefile.am
@@ -8,9 +8,9 @@ AUTOMAKE_OPTIONS = foreign 1.4
MP_H_FILES = eventmp.h mp.h msgmp.h partmp.h regionmp.h semmp.h signalmp.h \
taskmp.h
-STD_H_FILES = asr.h attr.h clock.h config.h dpmem.h event.h eventset.h \
- intr.h message.h modes.h options.h part.h ratemon.h region.h rtemsapi.h \
- sem.h signal.h status.h support.h tasks.h timer.h types.h
+STD_H_FILES = asr.h attr.h cache.h clock.h config.h dpmem.h event.h eventset.h \
+ intr.h message.h modes.h options.h part.h ratemon.h region.h rtemsapi.h sem.h \
+ signal.h status.h support.h tasks.h timer.h types.h
if HAS_MP
H_FILES = $(STD_H_FILES) $(MP_H_FILES)
diff --git a/c/src/exec/rtems/include/rtems/rtems/cache.h b/c/src/exec/rtems/include/rtems/rtems/cache.h
new file mode 100644
index 0000000000..1e71a9bf3a
--- /dev/null
+++ b/c/src/exec/rtems/include/rtems/rtems/cache.h
@@ -0,0 +1,140 @@
+/* cache.h
+ *
+ * Cache Manager
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ *
+ * The functions in this file define the API to the RTEMS Cache Manager and
+ * are divided into data cache and instruction cache functions. Data cache
+ * functions are only declared if a data cache is supported. Instruction
+ * cache functions are only declared if an instruction cache is supported.
+ * Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
+ * defined, where x E {DATA, INST}. These definitions are found in the CPU
+ * dependent source files in the supercore, often
+ *
+ * rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
+ *
+ * The functions below are implemented with CPU dependent inline routines
+ * also found in the above file. In the event that a CPU does not support a
+ * specific function, the CPU dependent routine does nothing (but does exist).
+ *
+ * At this point, the Cache Manager makes no considerations, and provides no
+ * support for BSP specific issues such as a secondary cache. In such a system,
+ * the CPU dependent routines would have to be modified, or a BSP layer added
+ * to this Manager.
+ */
+
+#ifndef __CACHE_h
+#define __CACHE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/system.h>
+#include <sys/types.h>
+
+
+/* THESE FUNCTIONS ONLY EXIST IF WE HAVE A DATA CACHE */
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+
+/*
+ * This function is called to flush the data cache by performing cache
+ * copybacks. It must determine how many cache lines need to be copied
+ * back and then perform the copybacks.
+ */
+void rtems_flush_multiple_data_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache invalidate.
+ * It must determine how many cache lines need to be invalidated and then
+ * perform the invalidations.
+ */
+void rtems_invalidate_multiple_data_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache flush.
+ * It flushes the entire cache.
+ */
+void rtems_flush_entire_data_cache( void );
+
+/*
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_invalidate_entire_data_cache( void );
+
+/*
+ * This function returns the data cache granularity.
+ */
+int rtems_get_data_cache_line_size( void );
+
+/*
+ * This function freezes the data cache.
+ */
+void rtems_freeze_data_cache( void );
+
+/*
+ * This function unfreezes the data cache.
+ */
+void rtems_unfreeze_data_cache( void );
+
+/*
+ * These functions enable/disable the data cache.
+ */
+void rtems_enable_data_cache( void );
+void rtems_disable_data_cache( void );
+#endif
+
+
+/* THESE FUNCTIONS ONLY EXIST IF WE HAVE AN INSTRUCTION CACHE */
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It must determine how many cache lines need to be invalidated
+ * and then perform the invalidations.
+ */
+void rtems_invalidate_multiple_inst_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_invalidate_entire_inst_cache( void );
+
+/*
+ * This function returns the instruction cache granularity.
+ */
+int rtems_get_inst_cache_line_size( void );
+
+/*
+ * This function freezes the instruction cache.
+ */
+void rtems_freeze_inst_cache( void );
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_inst_cache( void );
+
+/*
+ * These functions enable/disable the instruction cache.
+ */
+void rtems_enable_inst_cache( void );
+void rtems_disable_inst_cache( void );
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/exec/rtems/src/Makefile.am b/c/src/exec/rtems/src/Makefile.am
index f597292be1..f2b13c2aa9 100644
--- a/c/src/exec/rtems/src/Makefile.am
+++ b/c/src/exec/rtems/src/Makefile.am
@@ -50,7 +50,7 @@ PARTITION_C_FILES = part.c partcreate.c partdelete.c partgetbuffer.c \
DPMEM_C_FILES = dpmem.c dpmemcreate.c dpmemdelete.c dpmemexternal2internal.c \
dpmemident.c dpmeminternal2external.c
-STD_C_FILES = attr.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
+STD_C_FILES = attr.c cache.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
$(CLOCK_C_FILES) $(TIMER_C_FILES) $(SEMAPHORE_C_FILES) \
$(MESSAGE_QUEUE_C_FILES) $(EVENT_C_FILES) $(SIGNAL_C_FILES) \
$(PARTITION_C_FILES) $(REGION_C_FILES) $(DPMEM_C_FILES)
diff --git a/c/src/exec/rtems/src/cache.c b/c/src/exec/rtems/src/cache.c
new file mode 100644
index 0000000000..82d6410a92
--- /dev/null
+++ b/c/src/exec/rtems/src/cache.c
@@ -0,0 +1,252 @@
+/* cache.c
+ *
+ * Cache Manager
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ *
+ * The functions in this file define the API to the RTEMS Cache Manager and
+ * are divided into data cache and instruction cache functions. Data cache
+ * functions are only declared if a data cache is supported. Instruction
+ * cache functions are only declared if an instruction cache is supported.
+ * Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
+ * defined, where x E {DATA, INST}. These definitions are found in the CPU
+ * dependent source files in the supercore, often
+ *
+ * rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
+ *
+ * The functions below are implemented with CPU dependent inline routines
+ * also found in the above file. In the event that a CPU does not support a
+ * specific function, the CPU dependent routine does nothing (but does exist).
+ *
+ * At this point, the Cache Manager makes no considerations, and provides no
+ * support for BSP specific issues such as a secondary cache. In such a system,
+ * the CPU dependent routines would have to be modified, or a BSP layer added
+ * to this Manager.
+ */
+
+#include <rtems/system.h>
+#include <sys/types.h>
+#include <rtems/rtems/cache.h>
+
+
+/*
+ * THESE FUNCTIONS ONLY EXIST IF WE HAVE A DATA CACHE
+ */
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+
+/*
+ * This function is called to flush the data cache by performing cache
+ * copybacks. It must determine how many cache lines need to be copied
+ * back and then perform the copybacks.
+ */
+void
+rtems_flush_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
+{
+ const void * final_address;
+ /*
+ * Set d_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be pushed. Increment d_addr and push
+ * the resulting line until final_address is passed.
+ */
+ final_address = (void *)((size_t)d_addr + n_bytes - 1);
+ d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
+ while( d_addr <= final_address ) {
+ _CPU_flush_1_data_cache_line( d_addr );
+ d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
+ }
+}
+
+
+/*
+ * This function is responsible for performing a data cache invalidate.
+ * It must determine how many cache lines need to be invalidated and then
+ * perform the invalidations.
+ */
+void
+rtems_invalidate_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
+{
+ const void * final_address;
+ /*
+ * Set d_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be invalidated. Increment d_addr and
+ * invalidate the resulting line until final_address is passed.
+ */
+ final_address = (void *)((size_t)d_addr + n_bytes - 1);
+ d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
+ while( final_address > d_addr ) {
+ _CPU_invalidate_1_data_cache_line( d_addr );
+ d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
+ }
+}
+
+
+/*
+ * This function is responsible for performing a data cache flush.
+ * It flushes the entire cache.
+ */
+void
+rtems_flush_entire_data_cache( void )
+{
+ /*
+ * Call the CPU-specific routine
+ */
+ _CPU_flush_entire_data_cache();
+
+}
+
+
+/*
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void
+rtems_invalidate_entire_data_cache( void )
+{
+ /*
+ * Call the CPU-specific routine
+ */
+ _CPU_invalidate_entire_data_cache();
+}
+
+
+/*
+ * This function returns the data cache granularity.
+ */
+int
+rtems_get_data_cache_line_size( void )
+{
+ return _CPU_DATA_CACHE_ALIGNMENT;
+}
+
+
+/*
+ * This function freezes the data cache; cache lines
+ * are not replaced.
+ */
+void
+rtems_freeze_data_cache( void )
+{
+ _CPU_freeze_data_cache();
+}
+
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_data_cache( void )
+{
+ _CPU_unfreeze_data_cache();
+}
+
+
+/* Turn on the data cache. */
+void
+rtems_enable_data_cache( void )
+{
+ _CPU_enable_data_cache();
+}
+
+
+/* Turn off the data cache. */
+void
+rtems_disable_data_cache( void )
+{
+ _CPU_disable_data_cache();
+}
+#endif
+
+
+
+/*
+ * THESE FUNCTIONS ONLY EXIST IF WE HAVE AN INSTRUCTION CACHE
+ */
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It must determine how many cache lines need to be invalidated
+ * and then perform the invalidations.
+ */
+void
+rtems_invalidate_multiple_inst_cache_lines( const void * i_addr, size_t n_bytes )
+{
+ const void * final_address;
+ /*
+ * Set i_addr to the beginning of the cache line; final_address indicates
+ * the last address_t which needs to be invalidated. Increment i_addr and
+ * invalidate the resulting line until final_address is passed.
+ */
+ final_address = (void *)((size_t)i_addr + n_bytes - 1);
+ i_addr = (void *)((size_t)i_addr & ~(_CPU_INST_CACHE_ALIGNMENT - 1));
+ while( final_address > i_addr ) {
+ _CPU_invalidate_1_inst_cache_line( i_addr );
+ i_addr = (void *)((size_t)i_addr + _CPU_INST_CACHE_ALIGNMENT);
+ }
+}
+
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It invalidates the entire cache.
+ */
+void
+rtems_invalidate_entire_inst_cache( void )
+{
+ /*
+ * Call the CPU-specific routine
+ */
+ _CPU_invalidate_entire_inst_cache();
+}
+
+
+/*
+ * This function returns the instruction cache granularity.
+ */
+int
+rtems_get_inst_cache_line_size( void )
+{
+ return _CPU_INST_CACHE_ALIGNMENT;
+}
+
+
+/*
+ * This function freezes the instruction cache; cache lines
+ * are not replaced.
+ */
+void
+rtems_freeze_inst_cache( void )
+{
+ _CPU_freeze_inst_cache();
+}
+
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_inst_cache( void )
+{
+ _CPU_unfreeze_inst_cache();
+}
+
+
+/* Turn on the instruction cache. */
+void
+rtems_enable_inst_cache( void )
+{
+ _CPU_enable_inst_cache();
+}
+
+
+/* Turn off the instruction cache. */
+void
+rtems_disable_inst_cache( void )
+{
+ _CPU_disable_inst_cache();
+}
+#endif
diff --git a/c/src/exec/score/cpu/i386/rtems/score/i386.h b/c/src/exec/score/cpu/i386/rtems/score/i386.h
index f113ebee4e..ca1af66fff 100644
--- a/c/src/exec/score/cpu/i386/rtems/score/i386.h
+++ b/c/src/exec/score/cpu/i386/rtems/score/i386.h
@@ -144,6 +144,142 @@ static inline unsigned int i386_swap_U16(
}
+/*
+ * Added for pagination management
+ */
+
+static inline unsigned int i386_get_cr0()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr0(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
+}
+
+static inline unsigned int i386_get_cr2()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned int i386_get_cr3()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr3(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
+}
+
+/*
+ * Disable the entire cache
+ */
+void _CPU_disable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 1;
+ regCr0.cr0.no_write_through = 1;
+ i386_set_cr0( regCr0.i );
+ rtems_flush_entire_data_cache();
+}
+
+/*
+ * Enable the entire cache
+ */
+static inline void _CPU_enable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 0;
+ regCr0.cr0.no_write_through = 0;
+ i386_set_cr0( regCr0.i );
+ /*rtems_flush_entire_data_cache();*/
+}
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Definitions for I386_CACHE_ALIGNMENT are missing above for
+ * each CPU. The routines below should be implemented per CPU,
+ * to accomodate the capabilities of each.
+ */
+
+/* FIXME: I don't belong here. */
+#define I386_CACHE_ALIGNMENT 16
+
+#if defined(I386_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT
+
+static inline void _CPU_flush_1_data_cache_line (const void * d_addr) {}
+static inline void _CPU_invalidate_1_data_cache_line (const void * d_addr) {}
+static inline void _CPU_freeze_data_cache (void) {}
+static inline void _CPU_unfreeze_data_cache (void) {}
+static inline void _CPU_invalidate_1_inst_cache_line const void * d_addr() {}
+static inline void _CPU_freeze_inst_cache (void) {}
+static inline void _CPU_unfreeze_inst_cache (void) {}
+
+static inline void _CPU_flush_entire_data_cache (
+ const void * d_addr )
+{
+ asm ("wbinvd");
+}
+static inline void _CPU_invalidate_entire_data_cache (
+ const void * d_addr )
+{
+ asm ("invd");
+}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ _CPU_enable_cache();
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ _CPU_disable_cache();
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ const void * i_addr )
+{
+ asm ("invd");
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ _CPU_enable_cache();
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ _CPU_disable_cache();
+}
+#endif
+
+
/* routines */
/*
diff --git a/c/src/exec/score/cpu/m68k/rtems/score/m68k.h b/c/src/exec/score/cpu/m68k/rtems/score/m68k.h
index 64639220dd..c38a9a13ed 100644
--- a/c/src/exec/score/cpu/m68k/rtems/score/m68k.h
+++ b/c/src/exec/score/cpu/m68k/rtems/score/m68k.h
@@ -157,6 +157,7 @@ extern "C" {
# endif
#elif defined(__mc68302__)
+
#define CPU_MODEL_NAME "m68302"
#define M68K_HAS_VBR 0
#define M68K_HAS_SEPARATE_STACKS 0
@@ -350,16 +351,238 @@ static inline unsigned int m68k_swap_u16(
return( swapped );
}
-/* XXX this is only valid for some m68k family members and should be fixed */
+#define CPU_swap_u32( value ) m68k_swap_u32( value )
+#define CPU_swap_u16( value ) m68k_swap_u16( value )
+
+
+/*
+ * _CPU_virtual_to_physical
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to map virtual addresses to physical
+ * addresses.
+ *
+ * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
+ * PHYSICAL ADDRESSES
+ */
+static inline void * _CPU_virtual_to_physical (
+ const void * d_addr )
+{
+ return (void *) d_addr;
+}
+
+
+/*
+ * Since the cacr is common to all mc680x0, provide macros
+ * for masking values in that register.
+ */
-#define m68k_enable_caching() \
- { register unsigned32 _ctl=0x01; \
- asm volatile ( "movec %0,%%cacr" \
- : "=d" (_ctl) : "0" (_ctl) ); \
+/*
+ * Used to clear bits in the cacr.
+ */
+#define _CPU_CACR_AND(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ andl %2, %0; /* and with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
}
-#define CPU_swap_u32( value ) m68k_swap_u32( value )
-#define CPU_swap_u16( value ) m68k_swap_u16( value )
+
+/*
+ * Used to set bits in the cacr.
+ */
+#define _CPU_CACR_OR(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ orl %2, %0; /* or with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
+ }
+
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ */
+#if ( defined(__mc68020__) || defined(__mc68030__) )
+#define M68K_INST_CACHE_ALIGNMENT 16
+
+#if defined(__mc68030__)
+#define M68K_DATA_CACHE_ALIGNMENT 16
+
+/* Only the mc68030 has a data cache; it is writethrough only. */
+
+static inline void _CPU_flush_1_data_cache_line ( const void * d_addr ) {}
+static inline void _CPU_flush_entire_data_cache ( const void * d_addr ) {}
+
+static inline void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR(0x00000400);
+}
+
+static inline void _CPU_invalidate_entire_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000800 );
+}
+
+static inline void _CPU_freeze_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000200 );
+}
+
+static inline void _CPU_unfreeze_data_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFFFDFF );
+}
+
+static inline void _CPU_enable_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000100 );
+}
+static inline void _CPU_disable_data_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFEFF );
+}
+#endif
+
+
+/* Both the 68020 and 68030 have instruction caches */
+
+static inline void _CPU_invalidate_1_inst_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR( 0x00000004 );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000008 );
+}
+
+static inline void _CPU_freeze_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000002);
+}
+
+static inline void _CPU_unfreeze_inst_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFD );
+}
+
+static inline void _CPU_enable_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000001 );
+}
+
+static inline void _CPU_disable_inst_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFE );
+}
+
+
+#elif ( defined(__mc68040__) || defined (__mc68060__) )
+
+#define M68K_INST_CACHE_ALIGNMENT 16
+#define M68K_DATA_CACHE_ALIGNMENT 16
+
+/* Cannot be frozen */
+static inline void _CPU_freeze_data_cache ( void ) {}
+static inline void _CPU_unfreeze_data_cache ( void ) {}
+static inline void _CPU_freeze_inst_cache ( void ) {}
+static inline void _CPU_unfreeze_inst_cache ( void ) {}
+
+static inline void _CPU_flush_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cpushl %%dc,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cinvl %%dc,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_flush_entire_data_cache (
+ void )
+{
+ asm volatile ( "cpusha %%dc" :: );
+}
+
+static inline void _CPU_invalidate_entire_data_cache (
+ void )
+{
+ asm volatile ( "cinva %%dc" :: );
+}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x80000000 );
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ _CPU_CACR_AND( 0x7FFFFFFF );
+}
+
+static inline void _CPU_invalidate_1_inst_cache_line (
+ const void * i_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( i_addr );
+ asm volatile ( "cinvl %%ic,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ void )
+{
+ asm volatile ( "cinva %%ic" :: );
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00008000 );
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFF7FFF );
+}
+#endif
+
+
+#if defined(M68K_DATA_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT M68K_DATA_CACHE_ALIGNMENT
+#endif
+
+#if defined(M68K_INST_CACHE_ALIGNMENT)
+#define _CPU_INST_CACHE_ALIGNMENT M68K_INST_CACHE_ALIGNMENT
+#endif
+
#endif /* !ASM */
@@ -367,5 +590,5 @@ static inline unsigned int m68k_swap_u16(
}
#endif
-#endif
+#endif /* __M68K_h */
/* end of include file */
diff --git a/c/src/exec/score/cpu/powerpc/asm.h b/c/src/exec/score/cpu/powerpc/asm.h
index af14c95665..3c2e28ad5c 100644
--- a/c/src/exec/score/cpu/powerpc/asm.h
+++ b/c/src/exec/score/cpu/powerpc/asm.h
@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
+#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
+#endif /* ppc403 */
+
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
+#define dar 0x013 /* Data Address Register */
+#define dec 0x016 /* Decrementer Register */
+#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
+#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
+#define ictrl 0x09E /* Instruction Support Control Register */
+#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
+#endif
/*
* Following must be tailor for a particular flavor of the C compiler.
diff --git a/c/src/exec/score/cpu/powerpc/old_exception_processing/Makefile.am b/c/src/exec/score/cpu/powerpc/old_exception_processing/Makefile.am
index 9629808140..92f3fee811 100644
--- a/c/src/exec/score/cpu/powerpc/old_exception_processing/Makefile.am
+++ b/c/src/exec/score/cpu/powerpc/old_exception_processing/Makefile.am
@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
-C_FILES = cpu.c ppccache.c
+C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =
diff --git a/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.c b/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.c
index 7d6824cb26..5a5fadfd97 100644
--- a/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.c
+++ b/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.c
@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
+int _CPU_spurious_count = 0;
+int _CPU_last_spurious = 0;
+
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
+ ++_CPU_spurious_count;
+ _CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
- case PPC_IRQ_CPM_RESERVED_0:
+ case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:
diff --git a/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.h b/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.h
index 2a502d0745..30dd6dc092 100644
--- a/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.h
+++ b/c/src/exec/score/cpu/powerpc/old_exception_processing/cpu.h
@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
+#define _CPU_Data_Cache_Block_Invalidate( _address ) \
+ do { register void *__address = (_address); \
+ register unsigned32 _zero = 0; \
+ asm volatile ( "dcbi %0,%1" : \
+ "=r" (_zero), "=r" (__address) : \
+ "0" (_zero), "1" (__address) \
+ ); \
+ } while (0)
+
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
diff --git a/c/src/exec/score/cpu/powerpc/rtems/score/ppc.h b/c/src/exec/score/cpu/powerpc/rtems/score/ppc.h
index 83a54bfa25..682675efde 100644
--- a/c/src/exec/score/cpu/powerpc/rtems/score/ppc.h
+++ b/c/src/exec/score/cpu/powerpc/rtems/score/ppc.h
@@ -44,6 +44,8 @@
extern "C" {
#endif
+#include <rtems/score/ppctypes.h>
+
/*
* Define the name of the CPU family.
*/
@@ -220,6 +222,7 @@ extern "C" {
#elif defined(mpc860)
/*
* Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
+ * with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
*/
#define CPU_MODEL_NAME "PowerPC MPC860"
@@ -231,7 +234,6 @@ extern "C" {
#define PPC_HAS_FPU 0
#define PPC_HAS_DOUBLE 0
#define PPC_USE_MULTIPLE 1
-#define PPC_USE_SPRG 1
#define PPC_MSR_0 0x00009000
#define PPC_MSR_1 0x00001000
@@ -382,6 +384,157 @@ extern "C" {
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif
+#ifndef ASM
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Some functions simply have not been implemented.
+ */
+
+#if defined(ppc603) /* And possibly others */
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+/* Helpful macros */
+#define PPC_Get_HID0( _value ) \
+ do { \
+ _value = 0; /* to avoid warnings */ \
+ asm volatile( \
+ "mfspr %0, 0x3f0;" /* get HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+#define PPC_Set_HID0( _value ) \
+ do { \
+ asm volatile( \
+ "isync;" \
+ "mtspr 0x3f0, %0;" /* load HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00004000; /* set DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFFBFFF; /* clear DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00008000; /* Set ICE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFF7FFF; /* Clear ICE bit */
+ PPC_Set_HID0( value );
+}
+
+#elif ( defined(mpc860) || defined(mpc821) )
+
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+#define mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
+#define isync __asm__ volatile ("isync\n"::)
+
+static inline void _CPU_flush_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbf 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_flush_entire_data_cache ( void ) {}
+static inline void _CPU_invalidate_entire_data_cache ( void ) {}
+static inline void _CPU_freeze_data_cache ( void ) {}
+static inline void _CPU_unfreeze_data_cache ( void ) {}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_invalidate_1_inst_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "icbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache ( void ) {}
+static inline void _CPU_freeze_inst_cache ( void ) {}
+static inline void _CPU_unfreeze_inst_cache ( void ) {}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+#endif
+
+#endif /* !ASM */
+
/*
* Unless otherwise specified, assume the model has an IP/EP bit to
* set the exception address prefix.
@@ -550,7 +703,7 @@ extern "C" {
#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
-#define PPC_IRQ_CPM_RESERVED_0 (PPC_STD_IRQ_LAST + 26)
+#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)
diff --git a/c/src/exec/score/cpu/powerpc/shared/asm.h b/c/src/exec/score/cpu/powerpc/shared/asm.h
index af14c95665..3c2e28ad5c 100644
--- a/c/src/exec/score/cpu/powerpc/shared/asm.h
+++ b/c/src/exec/score/cpu/powerpc/shared/asm.h
@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
+#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
+#endif /* ppc403 */
+
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
+#define dar 0x013 /* Data Address Register */
+#define dec 0x016 /* Decrementer Register */
+#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
+#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
+#define ictrl 0x09E /* Instruction Support Control Register */
+#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
+#endif
/*
* Following must be tailor for a particular flavor of the C compiler.
diff --git a/c/src/exec/score/cpu/powerpc/shared/ppc.h b/c/src/exec/score/cpu/powerpc/shared/ppc.h
index 83a54bfa25..682675efde 100644
--- a/c/src/exec/score/cpu/powerpc/shared/ppc.h
+++ b/c/src/exec/score/cpu/powerpc/shared/ppc.h
@@ -44,6 +44,8 @@
extern "C" {
#endif
+#include <rtems/score/ppctypes.h>
+
/*
* Define the name of the CPU family.
*/
@@ -220,6 +222,7 @@ extern "C" {
#elif defined(mpc860)
/*
* Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
+ * with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
*/
#define CPU_MODEL_NAME "PowerPC MPC860"
@@ -231,7 +234,6 @@ extern "C" {
#define PPC_HAS_FPU 0
#define PPC_HAS_DOUBLE 0
#define PPC_USE_MULTIPLE 1
-#define PPC_USE_SPRG 1
#define PPC_MSR_0 0x00009000
#define PPC_MSR_1 0x00001000
@@ -382,6 +384,157 @@ extern "C" {
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif
+#ifndef ASM
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Some functions simply have not been implemented.
+ */
+
+#if defined(ppc603) /* And possibly others */
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+/* Helpful macros */
+#define PPC_Get_HID0( _value ) \
+ do { \
+ _value = 0; /* to avoid warnings */ \
+ asm volatile( \
+ "mfspr %0, 0x3f0;" /* get HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+#define PPC_Set_HID0( _value ) \
+ do { \
+ asm volatile( \
+ "isync;" \
+ "mtspr 0x3f0, %0;" /* load HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00004000; /* set DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFFBFFF; /* clear DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00008000; /* Set ICE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFF7FFF; /* Clear ICE bit */
+ PPC_Set_HID0( value );
+}
+
+#elif ( defined(mpc860) || defined(mpc821) )
+
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+#define mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
+#define isync __asm__ volatile ("isync\n"::)
+
+static inline void _CPU_flush_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbf 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_flush_entire_data_cache ( void ) {}
+static inline void _CPU_invalidate_entire_data_cache ( void ) {}
+static inline void _CPU_freeze_data_cache ( void ) {}
+static inline void _CPU_unfreeze_data_cache ( void ) {}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_invalidate_1_inst_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "icbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache ( void ) {}
+static inline void _CPU_freeze_inst_cache ( void ) {}
+static inline void _CPU_unfreeze_inst_cache ( void ) {}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+#endif
+
+#endif /* !ASM */
+
/*
* Unless otherwise specified, assume the model has an IP/EP bit to
* set the exception address prefix.
@@ -550,7 +703,7 @@ extern "C" {
#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
-#define PPC_IRQ_CPM_RESERVED_0 (PPC_STD_IRQ_LAST + 26)
+#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)
diff --git a/c/src/exec/score/include/rtems/score/object.h b/c/src/exec/score/include/rtems/score/object.h
index 811e33a17e..7640dce3d3 100644
--- a/c/src/exec/score/include/rtems/score/object.h
+++ b/c/src/exec/score/include/rtems/score/object.h
@@ -444,6 +444,21 @@ Objects_Control *_Objects_Get (
);
/*
+ * _Objects_Get_by_index
+ *
+ * DESCRIPTION:
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ */
+
+Objects_Control *_Objects_Get_by_index(
+ Objects_Information *information,
+ unsigned32 index,
+ Objects_Locations *location
+);
+
+/*
* _Objects_Get_next
*
* DESCRIPTION:
@@ -460,6 +475,25 @@ Objects_Control *_Objects_Get_next(
);
/*
+ * _Objects_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing object
+ * of the type specified by the information block pointer. Iteration
+ * continues until either all objects have been processed, or, if
+ * break_on_error is TRUE, until an invocation of the callback returns
+ * something other than 0.
+ */
+
+unsigned32 _Objects_Local_iterate(
+ Objects_Information *information,
+ unsigned32 (*callback)(Objects_Control *object, void * arg),
+ void * arg,
+ boolean break_on_error
+);
+
+/*
* Pieces of object.inl are promoted out to the user
*/
diff --git a/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h
index 4c8032f558..7739925e66 100644
--- a/c/src/exec/score/include/rtems/score/thread.h
+++ b/c/src/exec/score/include/rtems/score/thread.h
@@ -734,6 +734,23 @@ Thread_Control *_Thread_Get (
#endif
/*
+ * _Thread_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing thread.
+ * Iteration continues until either all threads have been processed, or,
+ * if break_on_error is TRUE, until an invocation of the callback returns
+ * an integer value other than 0.
+ */
+
+unsigned32 _Thread_Local_iterate(
+ unsigned32 (*callback)(Thread_Control *the_thread, void * arg),
+ void * arg,
+ boolean break_on_error
+);
+
+/*
* _Thread_Idle_body
*
* DESCRIPTION:
diff --git a/c/src/exec/score/src/Makefile.am b/c/src/exec/score/src/Makefile.am
index c348a606f1..97a2597cda 100644
--- a/c/src/exec/score/src/Makefile.am
+++ b/c/src/exec/score/src/Makefile.am
@@ -27,17 +27,18 @@ OBJECT_C_FILES = object.c objectallocate.c objectallocatebyindex.c \
objectclearname.c objectcomparenameraw.c objectcomparenamestring.c \
objectcopynameraw.c objectcopynamestring.c objectextendinformation.c \
objectfree.c objectget.c objectgetbyindex.c objectgetnext.c \
- objectinitializeinformation.c objectnametoid.c objectshrinkinformation.c
+ objectinitializeinformation.c objectlocaliterate.c objectnametoid.c \
+ objectshrinkinformation.c
THREAD_C_FILES = thread.c threadchangepriority.c threadclearstate.c \
threadclose.c threadcreateidle.c threaddelayended.c threaddispatch.c \
threadevaluatemode.c threadget.c threadhandler.c threadidlebody.c \
- threadinitialize.c threadloadenv.c threadready.c threadresettimeslice.c \
- threadreset.c threadrestart.c threadresume.c threadrotatequeue.c \
- threadsetpriority.c threadsetstate.c threadsettransient.c \
- threadstackallocate.c threadstackfree.c threadstart.c \
- threadstartmultitasking.c threadsuspend.c threadtickletimeslice.c \
- threadyieldprocessor.c
+ threadinitialize.c threadloadenv.c threadlocaliterate.c threadready.c \
+ threadresettimeslice.c threadreset.c threadrestart.c threadresume.c \
+ threadrotatequeue.c threadsetpriority.c threadsetstate.c \
+ threadsettransient.c threadstackallocate.c threadstackfree.c \
+ threadstart.c threadstartmultitasking.c threadsuspend.c \
+ threadtickletimeslice.c threadyieldprocessor.c
THREADQ_C_FILES = threadq.c threadqdequeue.c threadqdequeuefifo.c \
threadqdequeuepriority.c threadqenqueue.c threadqenqueuefifo.c \
@@ -53,8 +54,8 @@ WATCHDOG_C_FILES = watchdog.c watchdogadjust.c watchdoginsert.c \
watchdogremove.c watchdogtickle.c
STD_C_FILES = apiext.c chain.c $(CORE_MESSAGE_QUEUE_C_FILES) \
- $(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) interr.c \
- isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
+ $(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) \
+ interr.c isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
$(TOD_C_FILES) userext.c $(WATCHDOG_C_FILES) wkspace.c
if HAS_MP
diff --git a/c/src/exec/score/src/objectlocaliterate.c b/c/src/exec/score/src/objectlocaliterate.c
new file mode 100644
index 0000000000..e4b0f28de8
--- /dev/null
+++ b/c/src/exec/score/src/objectlocaliterate.c
@@ -0,0 +1,77 @@
+/*
+ * object iterator
+ *
+ *
+ * COPYRIGHT (c) 2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+
+/*PAGE
+ *
+ * _Objects_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing object
+ * of the type specified by the information block pointer. Iteration
+ * continues until either all objects have been processed, or, if
+ * break_on_error is TRUE, until an invocation of the callback returns
+ * something other than 0.
+ *
+ * Input parameters:
+ * information:
+ * A pointer to an Objects_Information block. Determines the type of
+ * object over which to iterate.
+ * callback:
+ * A pointer to a function with the indicated signature.
+ * arg:
+ * A pointer to some arbitrary entity. Passed on to the callback.
+ * break_on_error
+ * If TRUE, stop iterating on error.
+ *
+ * Output parameters: NONE
+ * But callback may write into space pointed to by arg.
+ *
+ * Return value:
+ * 0 if successful
+ * Value returned by the callback otherwise.
+ */
+
+unsigned32 _Objects_Local_iterate(
+ Objects_Information *information,
+ unsigned32 (*callback)(Objects_Control *object, void * arg),
+ void *arg,
+ boolean break_on_error
+)
+{
+ unsigned32 result;
+ unsigned32 i;
+ Objects_Control *the_object;
+
+ if ( !information )
+ return 0;
+
+ if ( !callback )
+ return 0;
+
+ for( i = 1; i <= information->maximum; i++ ) {
+ the_object = (Objects_Control *)information->local_table[i];
+ if( the_object ) {
+ result = (*callback)( the_object, arg );
+ if ( result && break_on_error )
+ return result;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/c/src/exec/score/src/threadlocaliterate.c b/c/src/exec/score/src/threadlocaliterate.c
new file mode 100644
index 0000000000..a2d94fe81a
--- /dev/null
+++ b/c/src/exec/score/src/threadlocaliterate.c
@@ -0,0 +1,77 @@
+/*
+ * Thread Iterator
+ *
+ *
+ * COPYRIGHT (c) 2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/score/thread.h>
+
+
+/*PAGE
+ *
+ * _Thread_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing thread.
+ * Iteration continues until either all threads have been processed, or,
+ * if break_on_error is TRUE, until an invocation of the callback returns
+ * an integer value other than 0.
+ *
+ * Input parameters:
+ * callback:
+ * A pointer to a function with the indicated signature.
+ * arg:
+ * A pointer to some arbitrary entity. Passed on to the callback.
+ * break_on_error
+ * If TRUE, stop iterating on error.
+ *
+ *
+ * Output parameters: NONE
+ * But callback may write into space pointed to by arg.
+ *
+ * Return value:
+ * 0 if successful
+ * Value returned by the callback otherwise.
+ */
+
+unsigned32 _Thread_Local_iterate(
+ unsigned32 (*callback)(Thread_Control *the_thread, void * arg),
+ void *arg,
+ boolean break_on_error
+)
+{
+ unsigned32 class_index;
+ unsigned32 result;
+ Objects_Information *information;
+
+ if( callback == NULL )
+ return 0;
+
+ for ( class_index = OBJECTS_CLASSES_FIRST ;
+ class_index <= OBJECTS_CLASSES_LAST ;
+ class_index++ ) {
+ information = _Objects_Information_table[ class_index ];
+ if ( information && information->is_thread ) {
+ result = _Objects_Local_iterate(
+ information,
+ (unsigned32 (*)(Objects_Control *, void *))callback,
+ arg,
+ break_on_error );
+ if( result && break_on_error )
+ return result;
+ }
+ }
+
+ return 0;
+}
diff --git a/c/src/lib/include/sys/termios.h b/c/src/lib/include/sys/termios.h
index 7cc28d7d38..199bb2aef2 100644
--- a/c/src/lib/include/sys/termios.h
+++ b/c/src/lib/include/sys/termios.h
@@ -181,6 +181,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, struct termios *);
+int tcdrain(int);
pid_t tcgetprgrp(int);
int tcsetprgrp(int, pid_t);
int tcsendbreak(int, int);
diff --git a/c/src/lib/libbsp/m68k/gen68360/startup/bspstart.c b/c/src/lib/libbsp/m68k/gen68360/startup/bspstart.c
index e129f2279e..80ca1749a4 100644
--- a/c/src/lib/libbsp/m68k/gen68360/startup/bspstart.c
+++ b/c/src/lib/libbsp/m68k/gen68360/startup/bspstart.c
@@ -32,6 +32,9 @@ rtems_cpu_table Cpu_table;
char *rtems_progname;
+/* Amount of RAM on this board. Dynamically set in start.S */
+unsigned long _M68K_RamSize;
+
/*
* Use the shared implementations of the following routines
*/
diff --git a/c/src/lib/libbsp/m68k/mvme167/README b/c/src/lib/libbsp/m68k/mvme167/README
index dc72a6fc48..861d07eac4 100644
--- a/c/src/lib/libbsp/m68k/mvme167/README
+++ b/c/src/lib/libbsp/m68k/mvme167/README
@@ -8,11 +8,12 @@ Please send any comments, improvements, or bug reports to:
Charles-Antoine Gauthier
charles.gauthier@nrc.ca
+
or
Darlene Stewart
Darlene.Stewart@nrc.ca
-
+
Software Engineering Group
Institute for Information Technology
National Research Council of Canada
@@ -20,19 +21,6 @@ Ottawa, ON, K1A 0R6
Canada
-WARNING:
---------
-
-The network driver is currently being worked on. It is somewhat functional,
-but it does run out of buffers under certain conditions. The code is
-also undergoing a substantial reorganization. Before making any changes,
-you should check with us for the availability of updates.
-
-Note from Joel: The ttcp performance reported is very nice even if the
-driver is still early in its life. :)
-
-
-
Disclaimer
----------
@@ -67,7 +55,6 @@ this file if you want S-records.
Port Description
Console driver
-
---------------
This BSP includes an termios-capable console driver that supports all
@@ -147,8 +134,62 @@ mvme167.cfg that redefine which variants of libc, libm and libgcc to link
against.
+Configuration Parameters
+
+If Jumper J1-4 is installed, certain configuration parameters may be read from
+the first 31 bytes of User Area NVRAM starting at 0xFFFC0000. In this case, the
+user is responsible for writing the appropriate values to this memory location
+(via 167Bug) in order to alter the default behaviour. A zero value results in
+the default behaviour. The paramaters that are configurable and their default
+settings are described below.
+
+ Data Cache Enable (0xFFFC0000 - 1 byte)
+ write a non-zero value to this location to enable the data cache
+ default: disabled
+
+ Instruction Cache Activation (0xFFFC0001 - 1 byte)
+ write a non-zero value to this location to enable the instruction cache
+ default: disabled
+
+ Cache Mode (0xFFFC0002 - 2 bytes)
+ 0xFFF0 = cachable, write-through
+ 0xFFF1 = cachable, copyback
+ 0xFFF2 = noncachable, serialized
+ 0xFFF3 = noncachable,
+ default: cachable, copyback
+
+ IP Address (0xFFFC0004 - 4 bytes)
+ write the hexidecimal representation of the board's IP address in this
+ location for example, 192.168.1.2 = 0xC0A80102
+ default: obtain the IP address from an rtems_bsdnet_ifconfig structure
+
+ Netmask (0xFFFC0008 - 4 bytes)
+ write the hexidecimal representation of the netmask in this location
+ for example, 255.255.255.0 = 0xFFFFFF00
+ default: obtain the netmask from an rtems_bsdnet_ifconfig structure
+
+ Ethernet Address (0xFFFC000C - 6 bytes)
+ write the board's hardware address in this location
+ default: obtain the hardware address from an rtems_bsdnet_ifconfig structure
+
+ Processor ID (0xFFFC0012 - 2 bytes)
+ reserved for future use
+
+ RMA start (0xFFFC0014 - 4 bytes)
+ reserved for future use
+
+ VMA start (0xFFFC0018 - 4 bytes)
+ reserved for future use
+
+ RamSize (0xFFFC001C - 4 bytes)
+ reserved for future use
+
+
Cache Control and Memory Mapping
+If configuration is not obtained from non-volatile RAM (ie. J1-4 is off),
+cache control is done through the remaining J1 jumpers as follows:
+
If Jumper J1-7 is installed, the data cache will be turned on. If Jumper
J1-6 is installed, the instruction cache will be turned on. Removing the
jumper causes the corresponding cache to be left disabled.
@@ -500,4 +541,3 @@ Timing tests:
rtems_rate_monotonic_period: conclude periods -- caller blocks 25
rtems_rate_monotonic_period: obtain status 13
-
diff --git a/c/src/lib/libbsp/m68k/mvme167/bsp_specs b/c/src/lib/libbsp/m68k/mvme167/bsp_specs
index efee788065..be4a31edff 100644
--- a/c/src/lib/libbsp/m68k/mvme167/bsp_specs
+++ b/c/src/lib/libbsp/m68k/mvme167/bsp_specs
@@ -10,7 +10,7 @@
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
-%{qjava: -lffi -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
+%{qjava: -lffi -lgcjgc -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
diff --git a/c/src/lib/libbsp/m68k/mvme167/include/bsp.h b/c/src/lib/libbsp/m68k/mvme167/include/bsp.h
index 1a95d9d576..913ca39bec 100644
--- a/c/src/lib/libbsp/m68k/mvme167/include/bsp.h
+++ b/c/src/lib/libbsp/m68k/mvme167/include/bsp.h
@@ -422,9 +422,9 @@ void BSP_output_string( char * buf );
* Representation of 82596CA LAN controller: Memory Map
*/
typedef volatile struct i82596_regs_ {
- unsigned short port_lower; /* 0xFFF46000 */
- unsigned short port_upper; /* 0xFFF46002 */
- unsigned long chan_attn; /* 0xFFF46004 */
+ unsigned short port_lower; /* 0xFFF46000 */
+ unsigned short port_upper; /* 0xFFF46002 */
+ unsigned long chan_attn; /* 0xFFF46004 */
} i82596_regs;
/*
@@ -432,6 +432,26 @@ typedef volatile struct i82596_regs_ {
*/
#define i82596 ((i82596_regs * const) 0xFFF46000)
+/*
+ * Representation of initialization data in NVRAM
+ */
+typedef volatile struct nvram_config_ {
+ unsigned char dcache_enable; /* 0xFFFC0000 */
+ unsigned char icache_enable; /* 0xFFFC0001 */
+ unsigned short cache_mode; /* 0xFFFC0002 */
+ unsigned long ipaddr; /* 0xFFFC0004 */
+ unsigned long netmask; /* 0xFFFC0008 */
+ unsigned char enaddr[6]; /* 0xFFFC000C */
+ unsigned short processor_id; /* 0xFFFC0012 */
+ unsigned long rma_start; /* 0xFFFC0014 */
+ unsigned long vma_start; /* 0xFFFC0018 */
+ unsigned long ramsize; /* 0xFFFC001C */
+} nvram_config;
+
+/*
+ * Pointer to the base of User Area NVRAM
+ */
+#define nvram ((nvram_config * const) 0xFFFC0000)
/* BSP-wide functions */
diff --git a/c/src/lib/libbsp/m68k/mvme167/network/network.c b/c/src/lib/libbsp/m68k/mvme167/network/network.c
index c8a2e71734..cce24b56be 100644
--- a/c/src/lib/libbsp/m68k/mvme167/network/network.c
+++ b/c/src/lib/libbsp/m68k/mvme167/network/network.c
@@ -40,6 +40,8 @@
#define UTI_596_ETH_MIN_SIZE 60
+#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
+
/*
* RTEMS events
*/
@@ -57,9 +59,11 @@
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
+#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
+#include <arpa/inet.h>
#include "uti596.h"
@@ -79,10 +83,10 @@
#define UTI596_DUMP_PORT_FUNCTION 3
/* Types of waiting for commands */
-#define UTI596_NO_WAIT 0
-#define UTI596_WAIT_FOR_CU_ACCEPT 1
-#define UTI596_WAIT_FOR_INITIALIZATION 2
-#define UTI596_WAIT_FOR_STAT_C 3
+#define UTI596_NO_WAIT 0
+#define UTI596_WAIT_FOR_CU_ACCEPT 1
+#define UTI596_WAIT_FOR_INITIALIZATION 2
+#define UTI596_WAIT_FOR_STAT_C 3
/* Device dependent data structure */
static uti596_softc_ uti596_softc;
@@ -417,6 +421,7 @@ static int uti596_portDump(
* Input parameters:
* sc - pointer to the uti596_softc struct
* wait_type - UTI596_NO_WAIT
+ * UTI596_WAIT
* UTI596_WAIT_FOR_CU_ACCEPT
* UTI596_WAIT_FOR_INITIALIZATION
* UTI596_WAIT_FOR_STAT_C
@@ -432,16 +437,18 @@ static int uti596_wait(
)
{
rtems_interval ticks_per_second, start_ticks, end_ticks;
-
+
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
switch( waitType ) {
+
case UTI596_NO_WAIT:
return 0;
- case UTI596_WAIT_FOR_CU_ACCEPT:
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
- end_ticks = start_ticks + ticks_per_second;
+ case UTI596_WAIT_FOR_CU_ACCEPT:
do {
if (sc->scb.command == 0)
break;
@@ -459,10 +466,6 @@ static int uti596_wait(
return 0;
case UTI596_WAIT_FOR_INITIALIZATION:
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
- end_ticks = start_ticks + ticks_per_second;
-
do {
if( !sc->iscp.busy )
break;
@@ -484,10 +487,6 @@ static int uti596_wait(
}
case UTI596_WAIT_FOR_STAT_C:
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
- end_ticks = start_ticks + ticks_per_second;
-
do {
if( *sc->pCurrent_command_status & STAT_C )
break;
@@ -1550,12 +1549,6 @@ void send_packet(
}
} while( m != NULL && ++bd_count < 16 );
- /* This should never happen */
- if ( bd_count == 16 ) {
- printk(("TX ERROR:Too many mbufs in the packet!!!\n"))
- printk(("Must coalesce!\n"))
- }
-
if ( length < UTI_596_ETH_MIN_SIZE ) {
pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */
pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */
@@ -1661,9 +1654,10 @@ int uti596_attach(
{
uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */
struct ifnet * ifp = &sc->arpcom.ac_if; /* ifnet structure */
-
- int unitNumber;
- char *unitName;
+ int unitNumber;
+ char *unitName;
+ char *pAddr;
+ int addr;
#ifdef DBG_ATTACH
printk(("uti596_attach: begins\n"))
@@ -1689,17 +1683,46 @@ int uti596_attach(
else
ifp->if_mtu = ETHERMTU;
- /* Ethernet address can be specified in the ifconfig structure or
- * it can be read in from BBRAM at $FFFC1F2C (6 bytes)
- * mvme167 manual p. 1-47
+ /*
+ * If an IP address and netmask are provided in NVRAM, cheat,
+ * and stuff them into the ifconfig structure, overriding any
+ * existing or NULL values.
+ *
+ * Warning: If values are provided in NVRAM, the ifconfig entries
+ * should be NULL because buffer memory allocated to hold the
+ * structure values is unrecoverable and would be lost here.
*/
- if ( pConfig->hardware_address) {
+ if ( addr = nvram->ipaddr ) {
+ if ( pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT ) )
+ pConfig->ip_address = inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );
+ else
+ rtems_panic("Can't allocate ip_address buffer!\n");
+ }
+ if ( addr = nvram->netmask ) {
+ if ( pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT ) )
+ pConfig->ip_netmask = inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );
+ else
+ rtems_panic("Can't allocate ip_netmask buffer!\n");
+ }
+
+ /* Ethernet address can be specified in NVRAM, or in the ifconfig
+ * structure. It will be read by default from BBRAM at $FFFC1F2C
+ * (6 bytes) mvme167 manual p. 1-47
+ */
+ if ( nvram->enaddr ) {
+ memcpy (sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);
+ }
+ else if ( pConfig->hardware_address) {
memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
}
else {
memcpy (sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
}
+ /* Possibly override default acceptance of broadcast packets */
+ if (pConfig->ignore_broadcast)
+ uti596initSetup[8] |= 0x02;
+
/* Assign requested receive buffer descriptor count */
if (pConfig->rbuf_count)
sc->rxBdCount = pConfig->rbuf_count;
@@ -1715,7 +1738,7 @@ int uti596_attach(
/* Set up fields in the ifnet structure*/
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_init = uti596_init;
+ ifp->if_init = uti596_init;
ifp->if_ioctl = uti596_ioctl;
ifp->if_start = uti596_start;
ifp->if_output = ether_output;
diff --git a/c/src/lib/libbsp/m68k/mvme167/startup/linkcmds b/c/src/lib/libbsp/m68k/mvme167/startup/linkcmds
index c22f578905..fc1733c069 100644
--- a/c/src/lib/libbsp/m68k/mvme167/startup/linkcmds
+++ b/c/src/lib/libbsp/m68k/mvme167/startup/linkcmds
@@ -17,12 +17,12 @@
*/
/* These are not really needed here */
-/* OUTPUT_FORMAT("elf32-m68k") */
+OUTPUT_FORMAT("elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
/*
- * Declare some sizes. Heap is sized at whatever ram space is left.
+ * Declare some sizes. Heap is sized at whatever ram space is left.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x00800000;
_RamSize = DEFINED(_RamSize) ? _RamSize : 4M;
diff --git a/c/src/lib/libbsp/m68k/mvme167/startup/page_table.c b/c/src/lib/libbsp/m68k/mvme167/startup/page_table.c
index ebbcc9739d..e6e5f1571a 100644
--- a/c/src/lib/libbsp/m68k/mvme167/startup/page_table.c
+++ b/c/src/lib/libbsp/m68k/mvme167/startup/page_table.c
@@ -32,11 +32,13 @@
* physical range 0x0 to 0x7FFFFFFF. We rely on the hardware to signal bus
* errors if we address non-existent memory within this range. Our two
* MVME167s are configured to exist at physical addresses 0x00800000 to
- * 0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. We map the space
- * from 0x0 to 0x7FFFFFFF as copyback, unless jumper J1-5 is removed, in
- * which case we map as writethrough. If jumper J1-7 is removed, the data
- * cache is NOT enabled. If jumper J1-6 is removed, the instruction cache
- * is not enabled.
+ * 0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. If jumper J1-4 is
+ * installed, memeory and cache control can be done by providing parameters
+ * in NVRAM. See the README for details. If J1-4 is removed, behaviour
+ * defaults to the following. We map the space from 0x0 to 0x7FFFFFFF as
+ * copyback, unless jumper J1-5 is removed, in which case we map as writethrough.
+ * If jumper J1-7 is removed, the data cache is NOT enabled. If jumper J1-6
+ * is removed, the instruction cache is not enabled.
*
* Copyright (c) 1998, National Research Council of Canada
*
@@ -84,23 +86,39 @@ void page_table_init(
*/
dtt0 = 0x007FC020;
- cacr = 0x80008000; /* Data and instruction cache on */
+ cacr = 0x00000000; /* Data and instruction cache off */
/* Read the J1 header */
j1 = (unsigned char)(lcsr->vector_base & 0xFF);
+
+ if ( !(j1 & 0x10) ) {
+ /* Jumper J1-4 is on, configure from NVRAM */
+
+ if ( nvram->dcache_enable )
+ cacr |= 0x80000000;
+
+ if ( nvram->icache_enable )
+ cacr |= 0x00008000;
+
+ if ( nvram->cache_mode )
+ dtt0 = ((nvram->cache_mode & 0x0003) << 5) | (dtt0 & 0xFFFFFF9F);
+ }
+ else {
+ /* Configure according to other jumper settings */
- if ( j1 & 0x80 )
- /* Jumper J1-7 if off, disable data caching */
- cacr &= 0x7FFFFFFF;
+ if ( j1 & 0x80 )
+ /* Jumper J1-7 if off, disable data caching */
+ cacr &= 0x7FFFFFFF;
- if ( j1 & 0x40 )
- /* Jumper J1-6 if off, disable instruction caching */
- cacr &= 0xFFFF7FFF;
+ if ( j1 & 0x40 )
+ /* Jumper J1-6 if off, disable instruction caching */
+ cacr &= 0xFFFF7FFF;
- if ( j1 & 0x20 )
- /* Jumper J1-5 is off, enable writethrough caching */
- dtt0 &= 0xFFFFFF9F;
-
+ if ( j1 & 0x20 )
+ /* Jumper J1-5 is off, enable writethrough caching */
+ dtt0 &= 0xFFFFFF9F;
+ }
+
/* do it ! */
asm volatile("movec %0, %%tc /* turn off paged address translation */
movec %0, %%cacr /* disable both caches */
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c b/c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c
index b5ba2b6495..08bd4628b2 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c
+++ b/c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c
@@ -16,7 +16,6 @@
*/
#include <stdio.h>
#include <bsp.h>
-#include <mpc860.h>
#include <rtems/error.h>
#include <canbus.h>
/* How many CAN interfaces are there? */
@@ -309,9 +308,9 @@ rtems_device_driver canbus_open(
candev[minor]->ctrl |= I82527_CTRL_IE;
candev[minor]->ctrl &= ~(I82527_CTRL_CCE | I82527_CTRL_INIT);
switch (minor) {
- case 0: m860.simask |= M860_SIMASK_IRM3; break;
- case 1: m860.simask |= M860_SIMASK_IRM4; break;
- case 2: m860.simask |= M860_SIMASK_IRM2; break;
+ case 0: m8xx.simask |= M8xx_SIMASK_IRM3; break;
+ case 1: m8xx.simask |= M8xx_SIMASK_IRM4; break;
+ case 2: m8xx.simask |= M8xx_SIMASK_IRM2; break;
default: return;
}
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/console/console.c b/c/src/lib/libbsp/powerpc/eth_comm/console/console.c
index cf7571815f..972803658b 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/console/console.c
+++ b/c/src/lib/libbsp/powerpc/eth_comm/console/console.c
@@ -27,9 +27,8 @@
* $Id$
*/
+#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
-#include <mpc860.h>
-#include <mpc860/console.h>
#include <termios.h>
rtems_device_driver console_initialize(rtems_device_major_number major,
@@ -37,8 +36,6 @@ rtems_device_driver console_initialize(rtems_device_major_number major,
void *arg)
{
rtems_status_code status;
- rtems_isr_entry old_handler;
- rtems_status_code sc;
#ifdef I_WANT_TERMIOS
/*
@@ -48,34 +45,23 @@ rtems_device_driver console_initialize(rtems_device_major_number major,
#endif
/*
- * Set up Buffer Descriptors
+ * Do common initialization.
*/
- m860_console_initialize();
+ m8xx_uart_initialize();
/*
* Do device-specific initialization
*/
- m860_scc_initialize(2); /* /dev/console */
- m860_scc_initialize(3); /* /dev/tty3 */
- m860_scc_initialize(4); /* /dev/tty4 */
- m860_smc_initialize(1); /* /dev/tty0 */
- m860_smc_initialize(2); /* /dev/tty1 */
+ m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
+ m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */
+ m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */
+ m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */
+ m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */
- sc = rtems_interrupt_catch (m860_scc2_console_interrupt_handler,
- PPC_IRQ_CPM_SCC2,
- &old_handler);
- sc = rtems_interrupt_catch (m860_scc3_console_interrupt_handler,
- PPC_IRQ_CPM_SCC3,
- &old_handler);
- sc = rtems_interrupt_catch (m860_scc4_console_interrupt_handler,
- PPC_IRQ_CPM_SCC4,
- &old_handler);
- sc = rtems_interrupt_catch (m860_smc1_console_interrupt_handler,
- PPC_IRQ_CPM_SMC1,
- &old_handler);
- sc = rtems_interrupt_catch (m860_smc2_console_interrupt_handler,
- PPC_IRQ_CPM_SMC2,
- &old_handler);
+ /*
+ * Set up interrupts
+ */
+ m8xx_uart_interrupts_initialize();
/*
* Register the devices
@@ -102,15 +88,15 @@ rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
- volatile m860SCCRegisters_t *sccregs;
+ volatile m8xxSCCRegisters_t *sccregs;
#ifdef I_WANT_TERMIOS
static const rtems_termios_callbacks sccPollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
- m860_char_poll_read, /* pollRead */
- m860_char_poll_write, /* write */
- m860_scc_set_attributes, /* setAttributes */
+ m8xx_uart_pollRead, /* pollRead */
+ m8xx_uart_pollWrite, /* write */
+ m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
@@ -121,30 +107,30 @@ rtems_device_driver console_open(rtems_device_major_number major,
switch (minor) {
case 0:
- m860.smc1.smcm = 1; /* Enable SMC1 RX interrupts */
- m860.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
+ m8xx.smc1.smcm = 1; /* Enable SMC1 RX interrupts */
+ m8xx.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
break;
case 1:
- m860.smc2.smcm = 1; /* Enable SMC2 RX interrupts */
- m860.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
+ m8xx.smc2.smcm = 1; /* Enable SMC2 RX interrupts */
+ m8xx.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
break;
case 2:
- m860.cimr |= 1UL << 30; /* Enable SCC1 interrupts */
- sccregs = &m860.scc1;
+ m8xx.cimr |= 1UL << 30; /* Enable SCC1 interrupts */
+ sccregs = &m8xx.scc1;
break;
case 3:
#ifndef I_WANT_TERMIOS
- m860.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
+ m8xx.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
#endif /* I_WANT_TERMIOS */
- sccregs = &m860.scc2;
+ sccregs = &m8xx.scc2;
break;
case 4:
- m860.cimr |= 1UL << 28; /* Enable SCC3 interrupts */
- sccregs = &m860.scc3;
+ m8xx.cimr |= 1UL << 28; /* Enable SCC3 interrupts */
+ sccregs = &m8xx.scc3;
break;
case 5:
- m860.cimr |= 1UL << 27; /* Enable SCC4 interrupts */
- sccregs = &m860.scc4;
+ m8xx.cimr |= 1UL << 27; /* Enable SCC4 interrupts */
+ sccregs = &m8xx.scc4;
break;
default:
rtems_panic ("CONSOLE: bad minor number");
@@ -186,14 +172,18 @@ rtems_device_driver console_read(rtems_device_major_number major,
void *arg)
{
#ifdef I_WANT_TERMIOS
+ /*
if (minor == SCC2_MINOR) {
+ */
return rtems_termios_read(arg);
+ /*
}
else {
- return m860_console_read(major, minor, arg);
+ return m8xx_console_read(major, minor, arg);
}
+ */
#else
- return m860_console_read(major, minor, arg);
+ return m8xx_console_read(major, minor, arg);
#endif
}
@@ -202,14 +192,18 @@ rtems_device_driver console_write(rtems_device_major_number major,
void *arg)
{
#ifdef I_WANT_TERMIOS
+ /*
if (minor == SCC2_MINOR) {
+ */
return rtems_termios_write(arg);
+ /*
}
else {
- return m860_console_write(major, minor, arg);
+ return m8xx_console_write(major, minor, arg);
}
+ */
#else
- return m860_console_write(major, minor, arg);
+ return m8xx_console_write(major, minor, arg);
#endif
}
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h b/c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h
index f7ccceedb2..ae9f4192c8 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h
@@ -24,6 +24,10 @@ extern "C" {
#include <rtems.h>
#include <console.h>
#include <clockdrv.h>
+#include <mpc8xx.h>
+#include <mpc8xx/cpm.h>
+#include <mpc8xx/mmu.h>
+#include <mpc8xx/console.h>
/*
* confdefs.h overrides for this BSP:
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/network/network.c b/c/src/lib/libbsp/powerpc/eth_comm/network/network.c
index e9cc9d9978..2fa25f664c 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/network/network.c
+++ b/c/src/lib/libbsp/powerpc/eth_comm/network/network.c
@@ -17,7 +17,6 @@
* $Id$
*/
#include <bsp.h>
-#include <mpc860.h>
#include <stdio.h>
#include <rtems/error.h>
#include <rtems/rtems_bsdnet.h>
@@ -80,8 +79,8 @@ struct m860_enet_struct {
int txBdHead;
int txBdTail;
int txBdActiveCount;
- m860BufferDescriptor_t *rxBdBase;
- m860BufferDescriptor_t *txBdBase;
+ m8xxBufferDescriptor_t *rxBdBase;
+ m8xxBufferDescriptor_t *txBdBase;
rtems_id rxDaemonTid;
rtems_id txDaemonTid;
@@ -118,11 +117,11 @@ m860_scc1_interrupt_handler (rtems_vector_number v)
/*
* Frame received?
*/
- if ((m860.scc1.sccm & 0x8) && (m860.scc1.scce & 0x8)) {
- m860.scc1.scce = 0x8;
+ if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) {
+ m8xx.scc1.scce = 0x8;
/* I don't think the next line is needed. It was in
* the 68360 stuff, though.
- * m860.scc1.sccm &= ~0x8;
+ * m8xx.scc1.sccm &= ~0x8;
*/
enet_driver[0].rxInterrupts++;
rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
@@ -131,16 +130,16 @@ m860_scc1_interrupt_handler (rtems_vector_number v)
/*
* Buffer transmitted or transmitter error?
*/
- if ((m860.scc1.sccm & 0x12) && (m860.scc1.scce & 0x12)) {
- m860.scc1.scce = 0x12;
+ if ((m8xx.scc1.sccm & 0x12) && (m8xx.scc1.scce & 0x12)) {
+ m8xx.scc1.scce = 0x12;
/* I don't think the next line is needed. It was in
* the 68360 stuff, though.
- * m860.scc1.sccm &= ~0x12;
+ * m8xx.scc1.sccm &= ~0x12;
*/
enet_driver[0].txInterrupts++;
rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
}
- m860.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
+ m8xx.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
}
/*
@@ -152,8 +151,8 @@ m860_fec_interrupt_handler (rtems_vector_number v)
/*
* Frame received?
*/
- if (m860.fec.ievent & M860_FEC_IEVENT_RFINT) {
- m860.fec.ievent = M860_FEC_IEVENT_RFINT;
+ if (m8xx.fec.ievent & M8xx_FEC_IEVENT_RFINT) {
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
enet_driver[0].rxInterrupts++;
rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
}
@@ -161,8 +160,8 @@ m860_fec_interrupt_handler (rtems_vector_number v)
/*
* Buffer transmitted or transmitter error?
*/
- if (m860.fec.ievent & M860_FEC_IEVENT_TFINT) {
- m860.fec.ievent = M860_FEC_IEVENT_TFINT;
+ if (m8xx.fec.ievent & M8xx_FEC_IEVENT_TFINT) {
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
enet_driver[0].txInterrupts++;
rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
}
@@ -182,31 +181,31 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Configure port A CLK1, CLK2, TXD1 and RXD1 pins
*/
- m860.papar |= 0x303;
- m860.padir &= ~0x303;
- m860.paodr &= ~0x303;
+ m8xx.papar |= 0x303;
+ m8xx.padir &= ~0x303;
+ m8xx.paodr &= ~0x303;
/*
* Configure port C CTS1* and CD1* pins, and PC4-PC7
*
*/
- m860.pcpar &= ~0x30;
- m860.pcdir |= 0x0f00;
- m860.pcdir &= ~0x30;
- m860.pcso |= 0x30;
- m860.pcdat &= ~0x0f00; /* Clear LOOP */
- m860.pcdat |= 0x0700; /* Set FULDL, TPSQEL, TPAPCE */
+ m8xx.pcpar &= ~0x30;
+ m8xx.pcdir |= 0x0f00;
+ m8xx.pcdir &= ~0x30;
+ m8xx.pcso |= 0x30;
+ m8xx.pcdat &= ~0x0f00; /* Clear LOOP */
+ m8xx.pcdat |= 0x0700; /* Set FULDL, TPSQEL, TPAPCE */
/*
* Connect CLK1 and CLK2 to SCC1
*/
- m860.sicr &= ~0xFF;
- m860.sicr |= (5 << 3) | 4;
+ m8xx.sicr &= ~0xFF;
+ m8xx.sicr |= (5 << 3) | 4;
/*
* Initialize SDMA configuration register
*/
- m860.sdcr = 1;
+ m8xx.sdcr = 1;
/*
* Allocate mbuf pointers
@@ -221,94 +220,94 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Set receiver and transmitter buffer descriptor bases
*/
- sc->rxBdBase = M860AllocateBufferDescriptors(sc->rxBdCount);
- sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
- m860.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m860;
- m860.scc1p.tbase = (char *)sc->txBdBase - (char *)&m860;
+ sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+ sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+ m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
+ m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;
/*
* Send "Init parameters" command
*/
- M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC1);
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);
/*
* Set receive and transmit function codes
*/
- m860.scc1p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
- m860.scc1p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
+ m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
+ m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
/*
* Set maximum receive buffer length
*/
- m860.scc1p.mrblr = RBUF_SIZE;
+ m8xx.scc1p.mrblr = RBUF_SIZE;
/*
* Set CRC parameters
*/
- m860.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
- m860.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
+ m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
+ m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
/*
* Clear diagnostic counters
*/
- m860.scc1p.un.ethernet.crcec = 0;
- m860.scc1p.un.ethernet.alec = 0;
- m860.scc1p.un.ethernet.disfc = 0;
+ m8xx.scc1p.un.ethernet.crcec = 0;
+ m8xx.scc1p.un.ethernet.alec = 0;
+ m8xx.scc1p.un.ethernet.disfc = 0;
/*
* Set pad value
*/
- m860.scc1p.un.ethernet.pads = 0x8888;
+ m8xx.scc1p.un.ethernet.pads = 0x8888;
/*
* Set retry limit
*/
- m860.scc1p.un.ethernet.ret_lim = 15;
+ m8xx.scc1p.un.ethernet.ret_lim = 15;
/*
* Set maximum and minimum frame length
*/
- m860.scc1p.un.ethernet.mflr = 1518;
- m860.scc1p.un.ethernet.minflr = 64;
- m860.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
- m860.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
+ m8xx.scc1p.un.ethernet.mflr = 1518;
+ m8xx.scc1p.un.ethernet.minflr = 64;
+ m8xx.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
+ m8xx.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
/*
* Clear group address hash table
*/
- m860.scc1p.un.ethernet.gaddr1 = 0;
- m860.scc1p.un.ethernet.gaddr2 = 0;
- m860.scc1p.un.ethernet.gaddr3 = 0;
- m860.scc1p.un.ethernet.gaddr4 = 0;
+ m8xx.scc1p.un.ethernet.gaddr1 = 0;
+ m8xx.scc1p.un.ethernet.gaddr2 = 0;
+ m8xx.scc1p.un.ethernet.gaddr3 = 0;
+ m8xx.scc1p.un.ethernet.gaddr4 = 0;
/*
* Set our physical address
*/
hwaddr = sc->arpcom.ac_enaddr;
- m860.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
- m860.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
- m860.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
+ m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
+ m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
+ m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
/*
* Aggressive retry
*/
- m860.scc1p.un.ethernet.p_per = 0;
+ m8xx.scc1p.un.ethernet.p_per = 0;
/*
* Clear individual address hash table
*/
- m860.scc1p.un.ethernet.iaddr1 = 0;
- m860.scc1p.un.ethernet.iaddr2 = 0;
- m860.scc1p.un.ethernet.iaddr3 = 0;
- m860.scc1p.un.ethernet.iaddr4 = 0;
+ m8xx.scc1p.un.ethernet.iaddr1 = 0;
+ m8xx.scc1p.un.ethernet.iaddr2 = 0;
+ m8xx.scc1p.un.ethernet.iaddr3 = 0;
+ m8xx.scc1p.un.ethernet.iaddr4 = 0;
/*
* Clear temp address
*/
- m860.scc1p.un.ethernet.taddr_l = 0;
- m860.scc1p.un.ethernet.taddr_m = 0;
- m860.scc1p.un.ethernet.taddr_h = 0;
+ m8xx.scc1p.un.ethernet.taddr_l = 0;
+ m8xx.scc1p.un.ethernet.taddr_m = 0;
+ m8xx.scc1p.un.ethernet.taddr_h = 0;
/*
* Set up receive buffer descriptors
@@ -330,7 +329,7 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Clear any outstanding events
*/
- m860.scc1.scce = 0xFFFF;
+ m8xx.scc1.scce = 0xFFFF;
/*
* Set up interrupts
@@ -342,21 +341,21 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
rtems_panic ("Can't attach M860 SCC1 interrupt handler: %s\n",
rtems_status_text (status));
}
- m860.scc1.sccm = 0; /* No interrupts unmasked till necessary */
- m860.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
+ m8xx.scc1.sccm = 0; /* No interrupts unmasked till necessary */
+ m8xx.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
/*
* Set up General SCC Mode Register
* Ethernet configuration
*/
- m860.scc1.gsmr_h = 0x0;
- m860.scc1.gsmr_l = 0x1088000c;
+ m8xx.scc1.gsmr_h = 0x0;
+ m8xx.scc1.gsmr_l = 0x1088000c;
/*
* Set up data synchronization register
* Ethernet synchronization pattern
*/
- m860.scc1.dsr = 0xd555;
+ m8xx.scc1.dsr = 0xd555;
/*
* Set up protocol-specific mode register
@@ -374,13 +373,13 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
* Wait 22 bits before looking for start of frame delimiter
* Disable full-duplex operation
*/
- m860.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
+ m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
/*
* Enable the TENA (RTS1*) pin
*/
- m860.pcpar |= 0x1;
- m860.pcdir &= ~0x1;
+ m8xx.pcpar |= 0x1;
+ m8xx.pcdir &= ~0x1;
/*
@@ -394,14 +393,14 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
- m860.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
+ m8xx.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
- m860.simask |= M860_SIMASK_LVM1;
+ m8xx.simask |= M8xx_SIMASK_LVM1;
/*
* Enable receiver and transmitter
*/
- m860.scc1.gsmr_l = 0x1088003c;
+ m8xx.scc1.gsmr_l = 0x1088003c;
}
static void
@@ -415,37 +414,37 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Issue reset to FEC
*/
- m860.fec.ecntrl=0x1;
+ m8xx.fec.ecntrl=0x1;
/*
* Put ethernet transciever in reset
*/
- m860.pgcra |= 0x80;
+ m8xx.pgcra |= 0x80;
/*
* Configure I/O ports
*/
- m860.pdpar = 0x1fff;
- m860.pddir = 0x1c58;
+ m8xx.pdpar = 0x1fff;
+ m8xx.pddir = 0x1c58;
/*
* Take ethernet transciever out of reset
*/
- m860.pgcra &= ~0x80;
+ m8xx.pgcra &= ~0x80;
/*
* Set SIU interrupt level to LVL2
*
*/
- m860.fec.ivec = 0x02 << 29;
+ m8xx.fec.ivec = 0x02 << 29;
/*
* Set the TX and RX fifo sizes. For now, we'll split it evenly
*/
/* If you uncomment these, the FEC will not work right.
- m860.fec.r_fstart = ((m860.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
- m860.fec.x_fstart = 0;
+ m8xx.fec.r_fstart = ((m8xx.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
+ m8xx.fec.x_fstart = 0;
*/
/*
@@ -453,20 +452,20 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
*/
hwaddr = sc->arpcom.ac_enaddr;
- m860.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
+ m8xx.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
(hwaddr[2] << 8) | (hwaddr[3] << 0);
- m860.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
+ m8xx.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
/*
* Clear the hash table
*/
- m860.fec.hash_table_high = 0;
- m860.fec.hash_table_low = 0;
+ m8xx.fec.hash_table_high = 0;
+ m8xx.fec.hash_table_low = 0;
/*
* Set up receive buffer size
*/
- m860.fec.r_buf_size = 0x5f0; /* set to 1520 */
+ m8xx.fec.r_buf_size = 0x5f0; /* set to 1520 */
/*
* Allocate mbuf pointers
@@ -481,10 +480,10 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Set receiver and transmitter buffer descriptor bases
*/
- sc->rxBdBase = M860AllocateBufferDescriptors(sc->rxBdCount);
- sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
- m860.fec.r_des_start = (int)sc->rxBdBase;
- m860.fec.x_des_start = (int)sc->txBdBase;
+ sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+ sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+ m8xx.fec.r_des_start = (int)sc->rxBdBase;
+ m8xx.fec.x_des_start = (int)sc->txBdBase;
/*
* Set up Receive Control Register:
@@ -493,21 +492,21 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
* Half duplex
* No loopback
*/
- m860.fec.r_cntrl = 0x00000006;
+ m8xx.fec.r_cntrl = 0x00000006;
/*
* Set up Transmit Control Register:
* Half duplex
* No heartbeat
*/
- m860.fec.x_cntrl = 0x00000000;
+ m8xx.fec.x_cntrl = 0x00000000;
/*
* Set up DMA function code:
* Big-endian
* DMA functino code = 0
*/
- m860.fec.fun_code = 0x78000000;
+ m8xx.fec.fun_code = 0x78000000;
/*
* Initialize SDMA configuration register
@@ -516,13 +515,13 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
* FEC arbitration ID = 0 => U-bus arbitration = 6
* RISC arbitration ID = 1 => U-bus arbitration = 5
*/
- m860.sdcr = 1;
+ m8xx.sdcr = 1;
/*
* Set MII speed to 2.5 MHz for 25 Mhz system clock
*/
- m860.fec.mii_speed = 0x0a;
- m860.fec.mii_data = 0x58021000;
+ m8xx.fec.mii_speed = 0x0a;
+ m8xx.fec.mii_data = 0x58021000;
/*
* Set up receive buffer descriptors
@@ -545,9 +544,9 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Mask all FEC interrupts and clear events
*/
- m860.fec.imask = M860_FEC_IEVENT_TFINT |
- M860_FEC_IEVENT_RFINT;
- m860.fec.ievent = ~0;
+ m8xx.fec.imask = M8xx_FEC_IEVENT_TFINT |
+ M8xx_FEC_IEVENT_RFINT;
+ m8xx.fec.ievent = ~0;
/*
* Set up interrupts
@@ -559,7 +558,7 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
rtems_panic ("Can't attach M860 FEC interrupt handler: %s\n",
rtems_status_text (status));
- m860.simask |= M860_SIMASK_LVM2;
+ m8xx.simask |= M8xx_SIMASK_LVM2;
}
@@ -583,44 +582,44 @@ m860Enet_retire_tx_bd (struct m860_enet_struct *sc)
i = sc->txBdTail;
nRetired = 0;
while ((sc->txBdActiveCount != 0)
- && (((status = (sc->txBdBase + i)->status) & M860_BD_READY) == 0)) {
+ && (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
/*
* See if anything went wrong
*/
- if (status & (M860_BD_DEFER |
- M860_BD_HEARTBEAT |
- M860_BD_LATE_COLLISION |
- M860_BD_RETRY_LIMIT |
- M860_BD_UNDERRUN |
- M860_BD_CARRIER_LOST)) {
+ if (status & (M8xx_BD_DEFER |
+ M8xx_BD_HEARTBEAT |
+ M8xx_BD_LATE_COLLISION |
+ M8xx_BD_RETRY_LIMIT |
+ M8xx_BD_UNDERRUN |
+ M8xx_BD_CARRIER_LOST)) {
/*
* Check for errors which stop the transmitter.
*/
- if (status & (M860_BD_LATE_COLLISION |
- M860_BD_RETRY_LIMIT |
- M860_BD_UNDERRUN)) {
- if (status & M860_BD_LATE_COLLISION)
+ if (status & (M8xx_BD_LATE_COLLISION |
+ M8xx_BD_RETRY_LIMIT |
+ M8xx_BD_UNDERRUN)) {
+ if (status & M8xx_BD_LATE_COLLISION)
enet_driver[0].txLateCollision++;
- if (status & M860_BD_RETRY_LIMIT)
+ if (status & M8xx_BD_RETRY_LIMIT)
enet_driver[0].txRetryLimit++;
- if (status & M860_BD_UNDERRUN)
+ if (status & M8xx_BD_UNDERRUN)
enet_driver[0].txUnderrun++;
/*
* Restart the transmitter
*/
/* FIXME: this should get executed only if using the SCC */
- M860ExecuteRISC (M860_CR_OP_RESTART_TX | M860_CR_CHAN_SCC1);
+ m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
}
- if (status & M860_BD_DEFER)
+ if (status & M8xx_BD_DEFER)
enet_driver[0].txDeferred++;
- if (status & M860_BD_HEARTBEAT)
+ if (status & M8xx_BD_HEARTBEAT)
enet_driver[0].txHeartbeat++;
- if (status & M860_BD_CARRIER_LOST)
+ if (status & M8xx_BD_CARRIER_LOST)
enet_driver[0].txLostCarrier++;
}
nRetired++;
- if (status & M860_BD_LAST) {
+ if (status & M8xx_BD_LAST) {
/*
* A full frame has been transmitted.
* Free all the associated buffer descriptors.
@@ -649,7 +648,7 @@ scc_rxDaemon (void *arg)
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_unsigned16 status;
- m860BufferDescriptor_t *rxBd;
+ m8xxBufferDescriptor_t *rxBd;
int rxBdIndex;
/*
@@ -662,9 +661,9 @@ scc_rxDaemon (void *arg)
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod (m, void *);
- rxBd->status = M860_BD_EMPTY | M860_BD_INTERRUPT;
+ rxBd->status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= M860_BD_WRAP;
+ rxBd->status |= M8xx_BD_WRAP;
break;
}
}
@@ -679,11 +678,11 @@ scc_rxDaemon (void *arg)
/*
* Wait for packet if there's not one ready
*/
- if ((status = rxBd->status) & M860_BD_EMPTY) {
+ if ((status = rxBd->status) & M8xx_BD_EMPTY) {
/*
* Clear old events
*/
- m860.scc1.scce = 0x8;
+ m8xx.scc1.scce = 0x8;
/*
* Wait for packet
@@ -692,13 +691,13 @@ scc_rxDaemon (void *arg)
* possibility that a packet arrived between the
* `if' above, and the clearing of the event register.
*/
- while ((status = rxBd->status) & M860_BD_EMPTY) {
+ while ((status = rxBd->status) & M8xx_BD_EMPTY) {
rtems_event_set events;
/*
* Unmask RXF (Full frame received) event
*/
- m860.scc1.sccm |= 0x8;
+ m8xx.scc1.sccm |= 0x8;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
@@ -710,16 +709,16 @@ scc_rxDaemon (void *arg)
/*
* Check that packet is valid
*/
- if ((status & (M860_BD_LAST |
- M860_BD_FIRST_IN_FRAME |
- M860_BD_LONG |
- M860_BD_NONALIGNED |
- M860_BD_SHORT |
- M860_BD_CRC_ERROR |
- M860_BD_OVERRUN |
- M860_BD_COLLISION)) ==
- (M860_BD_LAST |
- M860_BD_FIRST_IN_FRAME)) {
+ if ((status & (M8xx_BD_LAST |
+ M8xx_BD_FIRST_IN_FRAME |
+ M8xx_BD_LONG |
+ M8xx_BD_NONALIGNED |
+ M8xx_BD_SHORT |
+ M8xx_BD_CRC_ERROR |
+ M8xx_BD_OVERRUN |
+ M8xx_BD_COLLISION)) ==
+ (M8xx_BD_LAST |
+ M8xx_BD_FIRST_IN_FRAME)) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
@@ -747,29 +746,29 @@ scc_rxDaemon (void *arg)
/*
* Something went wrong with the reception
*/
- if (!(status & M860_BD_LAST))
+ if (!(status & M8xx_BD_LAST))
sc->rxNotLast++;
- if (!(status & M860_BD_FIRST_IN_FRAME))
+ if (!(status & M8xx_BD_FIRST_IN_FRAME))
sc->rxNotFirst++;
- if (status & M860_BD_LONG)
+ if (status & M8xx_BD_LONG)
sc->rxGiant++;
- if (status & M860_BD_NONALIGNED)
+ if (status & M8xx_BD_NONALIGNED)
sc->rxNonOctet++;
- if (status & M860_BD_SHORT)
+ if (status & M8xx_BD_SHORT)
sc->rxRunt++;
- if (status & M860_BD_CRC_ERROR)
+ if (status & M8xx_BD_CRC_ERROR)
sc->rxBadCRC++;
- if (status & M860_BD_OVERRUN)
+ if (status & M8xx_BD_OVERRUN)
sc->rxOverrun++;
- if (status & M860_BD_COLLISION)
+ if (status & M8xx_BD_COLLISION)
sc->rxCollision++;
}
/*
* Reenable the buffer descriptor
*/
- rxBd->status = (status & (M860_BD_WRAP | M860_BD_INTERRUPT)) |
- M860_BD_EMPTY;
+ rxBd->status = (status & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) |
+ M8xx_BD_EMPTY;
/*
* Move to next buffer descriptor
@@ -786,7 +785,7 @@ fec_rxDaemon (void *arg)
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_unsigned16 status;
- m860BufferDescriptor_t *rxBd;
+ m8xxBufferDescriptor_t *rxBd;
int rxBdIndex;
/*
@@ -799,10 +798,10 @@ fec_rxDaemon (void *arg)
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod (m, void *);
- rxBd->status = M860_BD_EMPTY;
- m860.fec.r_des_active = 0x1000000;
+ rxBd->status = M8xx_BD_EMPTY;
+ m8xx.fec.r_des_active = 0x1000000;
if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= M860_BD_WRAP;
+ rxBd->status |= M8xx_BD_WRAP;
break;
}
}
@@ -817,11 +816,11 @@ fec_rxDaemon (void *arg)
/*
* Wait for packet if there's not one ready
*/
- if ((status = rxBd->status) & M860_BD_EMPTY) {
+ if ((status = rxBd->status) & M8xx_BD_EMPTY) {
/*
* Clear old events
*/
- m860.fec.ievent = M860_FEC_IEVENT_RFINT;
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
/*
* Wait for packet
@@ -830,13 +829,13 @@ fec_rxDaemon (void *arg)
* possibility that a packet arrived between the
* `if' above, and the clearing of the event register.
*/
- while ((status = rxBd->status) & M860_BD_EMPTY) {
+ while ((status = rxBd->status) & M8xx_BD_EMPTY) {
rtems_event_set events;
/*
* Unmask RXF (Full frame received) event
*/
- m860.fec.ievent |= M860_FEC_IEVENT_RFINT;
+ m8xx.fec.ievent |= M8xx_FEC_IEVENT_RFINT;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
@@ -848,7 +847,7 @@ fec_rxDaemon (void *arg)
/*
* Check that packet is valid
*/
- if (status & M860_BD_LAST) {
+ if (status & M8xx_BD_LAST) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
@@ -876,27 +875,27 @@ fec_rxDaemon (void *arg)
/*
* Something went wrong with the reception
*/
- if (!(status & M860_BD_LAST))
+ if (!(status & M8xx_BD_LAST))
sc->rxNotLast++;
- if (status & M860_BD_LONG)
+ if (status & M8xx_BD_LONG)
sc->rxGiant++;
- if (status & M860_BD_NONALIGNED)
+ if (status & M8xx_BD_NONALIGNED)
sc->rxNonOctet++;
- if (status & M860_BD_SHORT)
+ if (status & M8xx_BD_SHORT)
sc->rxRunt++;
- if (status & M860_BD_CRC_ERROR)
+ if (status & M8xx_BD_CRC_ERROR)
sc->rxBadCRC++;
- if (status & M860_BD_OVERRUN)
+ if (status & M8xx_BD_OVERRUN)
sc->rxOverrun++;
- if (status & M860_BD_COLLISION)
+ if (status & M8xx_BD_COLLISION)
sc->rxCollision++;
}
/*
* Reenable the buffer descriptor
*/
- rxBd->status = (status & M860_BD_WRAP) |
- M860_BD_EMPTY;
- m860.fec.r_des_active = 0x1000000;
+ rxBd->status = (status & M8xx_BD_WRAP) |
+ M8xx_BD_EMPTY;
+ m8xx.fec.r_des_active = 0x1000000;
/*
* Move to next buffer descriptor
*/
@@ -909,7 +908,7 @@ static void
scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
{
struct m860_enet_struct *sc = ifp->if_softc;
- volatile m860BufferDescriptor_t *firstTxBd, *txBd;
+ volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
struct mbuf *l = NULL;
rtems_unsigned16 status;
int nAdded;
@@ -936,7 +935,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Clear old events
*/
- m860.scc1.scce = 0x12;
+ m8xx.scc1.scce = 0x12;
/*
* Wait for buffer descriptor to become available.
@@ -958,7 +957,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Unmask TXB (buffer transmitted) and
* TXE (transmitter error) events.
*/
- m860.scc1.sccm |= 0x12;
+ m8xx.scc1.sccm |= 0x12;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
@@ -971,7 +970,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Don't set the READY flag till the
* whole packet has been readied.
*/
- status = nAdded ? M860_BD_READY : 0;
+ status = nAdded ? M8xx_BD_READY : 0;
/*
* FIXME: Why not deal with empty mbufs at at higher level?
@@ -990,7 +989,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
sc->txMbuf[sc->txBdHead] = m;
nAdded++;
if (++sc->txBdHead == sc->txBdCount) {
- status |= M860_BD_WRAP;
+ status |= M8xx_BD_WRAP;
sc->txBdHead = 0;
}
l = m;
@@ -1013,9 +1012,9 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
*/
if (m == NULL) {
if (nAdded) {
- status |= M860_BD_PAD | M860_BD_LAST | M860_BD_TX_CRC | M860_BD_INTERRUPT;
+ status |= M8xx_BD_PAD | M8xx_BD_LAST | M8xx_BD_TX_CRC | M8xx_BD_INTERRUPT;
txBd->status = status;
- firstTxBd->status |= M860_BD_READY;
+ firstTxBd->status |= M8xx_BD_READY;
sc->txBdActiveCount += nAdded;
}
break;
@@ -1029,7 +1028,7 @@ static void
fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
{
struct m860_enet_struct *sc = ifp->if_softc;
- volatile m860BufferDescriptor_t *firstTxBd, *txBd;
+ volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
/* struct mbuf *l = NULL; */
rtems_unsigned16 status;
int nAdded;
@@ -1037,7 +1036,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Free up buffer descriptors
*/
- m860Enet_retire_tx_bd (sc);
+ m8xxEnet_retire_tx_bd (sc);
/*
* Set up the transmit buffer descriptors.
@@ -1056,7 +1055,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Clear old events
*/
- m860.fec.ievent = M860_FEC_IEVENT_TFINT;
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
/*
* Wait for buffer descriptor to become available.
@@ -1078,7 +1077,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Unmask TXB (buffer transmitted) and
* TXE (transmitter error) events.
*/
- m860.fec.ievent |= M860_FEC_IEVENT_TFINT;
+ m8xx.fec.ievent |= M8xx_FEC_IEVENT_TFINT;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
@@ -1091,7 +1090,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Don't set the READY flag till the
* whole packet has been readied.
*/
- status = nAdded ? M860_BD_READY : 0;
+ status = nAdded ? M8xx_BD_READY : 0;
/*
* FIXME: Why not deal with empty mbufs at at higher level?
@@ -1110,7 +1109,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
sc->txMbuf[sc->txBdHead] = m;
nAdded++;
if (++sc->txBdHead == sc->txBdCount) {
- status |= M860_BD_WRAP;
+ status |= M8xx_BD_WRAP;
sc->txBdHead = 0;
}
/* l = m;*/
@@ -1135,10 +1134,10 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
*/
if (m == NULL) {
if (nAdded) {
- status |= M860_BD_LAST | M860_BD_TX_CRC;
+ status |= M8xx_BD_LAST | M8xx_BD_TX_CRC;
txBd->status = status;
- firstTxBd->status |= M860_BD_READY;
- m860.fec.x_des_active = 0x1000000;
+ firstTxBd->status |= M8xx_BD_READY;
+ m8xx.fec.x_des_active = 0x1000000;
sc->txBdActiveCount += nAdded;
}
break;
@@ -1254,9 +1253,9 @@ scc_init (void *arg)
* Set flags appropriately
*/
if (ifp->if_flags & IFF_PROMISC)
- m860.scc1.psmr |= 0x200;
+ m8xx.scc1.psmr |= 0x200;
else
- m860.scc1.psmr &= ~0x200;
+ m8xx.scc1.psmr &= ~0x200;
/*
* Tell the world that we're running.
@@ -1266,7 +1265,7 @@ scc_init (void *arg)
/*
* Enable receiver and transmitter
*/
- m860.scc1.gsmr_l |= 0x30;
+ m8xx.scc1.gsmr_l |= 0x30;
}
static void
@@ -1294,9 +1293,9 @@ fec_init (void *arg)
* Set flags appropriately
*/
if (ifp->if_flags & IFF_PROMISC)
- m860.fec.r_cntrl |= 0x8;
+ m8xx.fec.r_cntrl |= 0x8;
else
- m860.fec.r_cntrl &= ~0x8;
+ m8xx.fec.r_cntrl &= ~0x8;
/*
@@ -1307,7 +1306,7 @@ fec_init (void *arg)
/*
* Enable receiver and transmitter
*/
- m860.fec.ecntrl = 0x2;
+ m8xx.fec.ecntrl = 0x2;
}
@@ -1324,7 +1323,7 @@ scc_stop (struct m860_enet_struct *sc)
/*
* Shut down receiver and transmitter
*/
- m860.scc1.gsmr_l &= ~0x30;
+ m8xx.scc1.gsmr_l &= ~0x30;
}
static void
@@ -1337,7 +1336,7 @@ fec_stop (struct m860_enet_struct *sc)
/*
* Shut down receiver and transmitter
*/
- m860.fec.ecntrl = 0x0;
+ m8xx.fec.ecntrl = 0x0;
}
/*
@@ -1355,7 +1354,7 @@ enet_stats (struct m860_enet_struct *sc)
printf (" Bad CRC:%-8lu", sc->rxBadCRC);
printf (" Overrun:%-8lu", sc->rxOverrun);
printf (" Collision:%-8lu\n", sc->rxCollision);
- printf (" Discarded:%-8lu\n", (unsigned long)m860.scc1p.un.ethernet.disfc);
+ printf (" Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);
printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
printf (" Deferred:%-8lu", sc->txDeferred);
@@ -1610,7 +1609,7 @@ rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config)
{
int i;
- if ((m860.fec.mii_data & 0xffff) == 0x2000) {
+ if ((m8xx.fec.mii_data & 0xffff) == 0x2000) {
/* rtems_scc1_driver_attach(config);*/
return rtems_fec_driver_attach(config);
}
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c b/c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c
index be35333ea5..c5c1c37d76 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c
@@ -18,7 +18,6 @@
*/
#include <bsp.h>
-#include <mpc860.h>
#include <rtems/libio.h>
#include <libcsupport.h>
@@ -115,6 +114,10 @@ void bsp_start(void)
extern int _end;
rtems_unsigned32 heap_start;
rtems_unsigned32 ws_start;
+
+ cpu_init();
+ mmu_init();
+
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
@@ -166,16 +169,14 @@ void bsp_start(void)
* transciever that is used for 10/100 Mbps ethernet now, so that
* we can attempt to read it later in rtems_enet_driver_attach()
*/
- m860.fec.mii_speed = 0x0a;
- m860.fec.mii_data = 0x680a0000;
-
+ m8xx.fec.mii_speed = 0x0a;
+ m8xx.fec.mii_data = 0x680a0000;
- m860.scc2.sccm=0;
- m860.scc2p.rbase=0;
- m860.scc2p.tbase=0;
- M860ExecuteRISC(M860_CR_OP_STOP_TX | M860_CR_CHAN_SCC2);
- mmu_init();
+ m8xx.scc2.sccm=0;
+ m8xx.scc2p.rbase=0;
+ m8xx.scc2p.tbase=0;
+ m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
}
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/startup/cpuinit.c b/c/src/lib/libbsp/powerpc/eth_comm/startup/cpuinit.c
new file mode 100644
index 0000000000..6049f37878
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/eth_comm/startup/cpuinit.c
@@ -0,0 +1,44 @@
+/*
+ * cpuinit.c - this file contains functions for initializing the CPU
+ *
+ * Written by Jay Monkman (jmonkman@frasca.com)
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+
+/* Macros for handling all the MMU SPRs */
+#define PUT_IC_CST(r) __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
+#define GET_IC_CST(r) __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
+#define PUT_DC_CST(r) __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
+#define GET_DC_CST(r) __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
+
+void cpu_init(void)
+{
+ register unsigned long t1, t2;
+
+ /* Let's clear MSR[IR] and MSR[DR] */
+ t2 = PPC_MSR_IR | PPC_MSR_DR;
+ __asm__ volatile (
+ "mfmsr %0\n"
+ "andc %0, %0, %1\n"
+ "mtmsr %0\n" :"=r"(t1), "=r"(t2):
+ "1"(t2));
+
+ t1 = M8xx_CACHE_CMD_UNLOCK;
+ /* PUT_DC_CST(t1); */
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_INVALIDATE;
+ /* PUT_DC_CST(t1); */
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_ENABLE;
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_SFWT;
+ /* PUT_DC_CST(t1); */
+ t1 = M8xx_CACHE_CMD_ENABLE;
+ /* PUT_DC_CST(t1);*/
+}
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds b/c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds
index d2a072876f..a565798488 100644
--- a/c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds
+++ b/c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds
@@ -128,8 +128,8 @@ SECTIONS
dpram :
{
- m860 = .;
- _m860 = .;
+ m8xx = .;
+ _m8xx = .;
. += (8 * 1024);
} >dpram
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/startup/mmutlbtab.c b/c/src/lib/libbsp/powerpc/eth_comm/startup/mmutlbtab.c
new file mode 100644
index 0000000000..2153ccccab
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/eth_comm/startup/mmutlbtab.c
@@ -0,0 +1,45 @@
+/*
+ * mmutlbtab.c
+ *
+ * This file defines the MMU_TLB_table for the eth_comm board.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+
+/*
+ * This MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of the MPC860 processor.
+ *
+ * We initialize the entries in both the instruction and data TLBs
+ * with the same values - a few bits relevant to the data TLB are unused
+ * in the instruction TLB.
+ *
+ * An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
+ * Real Page Number (RPN) value are supplied in the table for each TLB entry.
+ *
+ * The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
+ * not have more than 32 lines in it!
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+MMU_TLB_table_t MMU_TLB_table[] = {
+ /*
+ * DRAM: CS1, Start address 0x00000000, 8M,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for supervisor, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0x00000200, 0x0D, 0x000001FD } /* DRAM - PS=PS=8M */
+};
+
+/*
+ * MMU_N_TLB_Table_Entries is defined here because the size of the
+ * MMU_TLB_table is only known in this file.
+ */
+int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/Makefile.am
new file mode 100644
index 0000000000..fbbb0bf6c2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/Makefile.am
@@ -0,0 +1,17 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
+
+# wrapup is the one that actually builds and installs the library
+# from the individual .rel files built in other directories
+SUBDIRS = console include network startup wrapup
+
+include $(top_srcdir)/../../bsp.am
+
+EXTRA_DIST = README bsp_specs times
+
+include $(top_srcdir)/../../../../../../automake/subdirs.am
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/README b/c/src/lib/libbsp/powerpc/mbx8xx/README
new file mode 100644
index 0000000000..7a1c9fe5b2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/README
@@ -0,0 +1,372 @@
+This is a README file for the MBX860/MBX821 port of RTEMS 4.5.0
+
+Please send any comments, improvements, or bug reports to:
+
+Darlene A. Stewart
+Software Engineering Group
+Institute for Information Technology
+National Research Council of Canada
+Ottawa, ON, K1A 0R6
+Canada
+
+Darlene.Stewart@nrc.ca
+
+
+
+Disclaimer
+----------
+
+The National Research Council of Canada is distributing this RTEMS
+board support package for the Motorola MBX860 and MBX821 as free
+software; you can redistribute it and/or modify it under 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 software 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 RTEMS; see file
+COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+Under no circumstances will the National Research Council of Canada
+nor Her Majesty the Queen in right of Canada assume any liablility
+for the use this software, nor any responsibility for its quality or
+its support.
+
+
+Summary
+-------
+
+BSP NAME: mbx8xx
+BOARD: Motorola MBX860 and MBX821 Embedded Controllers
+BUS: No backplane. On-board ISA, PCI, PC/104 and PCMCIA.
+CPU FAMILY: PowerPC
+CPU: PowerPC MPC860 or MPC821
+COPROCESSORS: Built-in Motorola QUICC
+MODE: 32 bit mode
+
+DEBUG MONITOR: EPPC-Bug
+
+PERIPHERALS
+===========
+TIMERS: PIT / Timebase
+ RESOLUTION: 1 microsecond / frequency = clock-speed / 16
+SERIAL PORTS: 2 or 4 SCCs (SCC1 is hardwired for Ethernet)
+ 2 SMC
+ 1 SIO
+REAL-TIME CLOCK: Many. Look at documentation.
+DMA: Each SCC and SMC.
+VIDEO: None on-board. MPC821 has a built-in LCD panel driver.
+SCSI: None on-board.
+NETWORKING: Ethernet (10 Mbps) on SCC1
+
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER: yes
+CONSOLE DRIVER: yes
+SHMSUPP: N/A
+TIMER DRIVER: yes
+NETWORK DRIVER: yes
+
+NOTES
+=====
+On-chip resources:
+ SCC1 network or console
+ SCC2 serial port
+ SMC1 gdb debug console/application console
+ SMC2 application console
+ CLK1 network
+ CLK2 network
+ CLK3
+ CLK4
+ CLK5
+ CLK6
+ CLK7
+ CLK8
+ BRG1 console
+ BRG2 console
+ BRG3 console
+ BRG4 console
+ RTC
+ PIT clock
+ TB
+ DEC
+ SWT
+ *CS0 FLASH
+ *CS1 DRAM bank (onboard)
+ *CS2 DRAM bank 0 (1st half of DIMM)
+ *CS3 DRAM bank 1 (2nd half of DIMM)
+ *CS4 Battery-Backed SRAM
+ *CS5 QSPAN PCI
+ *CS6 QSPAN
+ *CS7 Boot ROM
+ UPMA
+ UPMB
+ IRQ0
+ IRQ1
+ IRQ2
+ IRQ3
+ IRQ4
+ IRQ5
+ IRQ6
+ IRQ7
+ IRQ_LVL0
+ IRQ_LVL1
+ IRQ_LVL2
+ IRQ_LVL3
+ IRQ_LVL4
+ IRQ_LVL5
+ IRQ_LVL6
+ IRQ_LVL7
+
+
+Board description
+-----------------
+Clock rate: 50MHz Entry level boards, 40 MHz others.
+Bus width: 8/32 bit Flash, 32 bit DRAM
+FLASH: 2-4MB, 120ns
+RAM: 4-16MB EDO, 60ns DRAM DIMM
+
+
+Installation
+------------
+
+All MBX821/MBX860 ports share the same source code base. The MPC821 does
+not have SCC3 and SCC4. Instead, it has an LCD panel driver. Otherwise,
+the MBX821 and MBX860 boards are essentially identical. Entry level boards
+do not have all connectors and peripheral devices present. This has no
+impact on the source code base; it merely means that some functionality
+is not available on these entry level boards. For the most part, the port
+uses the standard build process for powerpc targets. However, you must
+specify the EXACT model of MBX board that you are building for as the
+argument to the RTEMS_BSP make variable. If you do not, the build process
+will build for a MBX860-002. Look at rtems/make/custom/mbx8xx.cfg for the
+specific list of boards supported and their corresponding names. An
+example build command is:
+
+ make RTEMS_BSP=mbx821_001 all debug
+
+This will build the optimized and debug versions of all RTEMS libraries,
+samples and tests (if the latter are enabled).
+
+The Software Engineering Group of the Institute for Information Technology
+only owns an MBX821-001 and MBX86-002. The only provided config files are
+mbx821_001.cfg and mbx860_002.cfg. A SPECIFIC CONFIG FILE IS REQUIRED. Use
+one of the provided files as a template to create a specific config file for
+another model.
+
+We rely on EPPC-BUG to download to the targets. We use the 'PLH" command.
+We enabled a TFTP deamon on our development host.
+
+
+Port Description
+Console driver
+---------------
+
+This BSP includes an termios-capable console driver that supports SMC1,
+SMC2, SCC2, and SCC3 and SCC4 if present. The RTEMS console is selected
+in rtems/make/custom/mbx8xx.cfg with the CONSOLE_MINOR variable. We
+normally run with the RTEMS application console on SMC1.
+
+Support is provided for polled and interrupt-driven terminal I/O. Interrupt-
+driven I/O is selected by setting the UARTS_USE_INTERRUPTS variable in
+rtems/make/custom/mbx8xx.cfg. If the variable is not set, or if it is set
+to zero, polled I/O is used. If the EPPCBUG_SMC1 variable is set in
+rtems/make/custom/mbx8xx.cfg, SMC1 will be used in polled mode with all
+I/O done by EPPC-Bug rather than the supplied device driver. This mode
+should be used if the application console is shared with EPPC-Bug.
+
+Polled I/O must be used when running the timing tests. It must also be used
+to run some other tests and some samples, such as the cdtest. Applications
+would normally use interrupt-driven I/O.
+
+
+EPPC-Bug and I/O
+----------------
+
+Be warned that when EPPC-Bug does I/O through a serial port, all interrupts
+get turned off in the SIMASK register! This is a definite bug in release 1.1
+of the firmware. It may have been fixed in later releases.
+
+To solve this problem that occurs when GDB communicates with EPPC-Bug,
+whenever the BSP manipulates the SIMASK, it makes copy of the written
+in a global variable called 'simask_copy'. That value must be restored by
+GDB before execution resumes. The following commands placed in the .gdbinit
+file takes care of this:
+
+# GDB Initialization file for EPPCBug.
+
+define hook-stepi
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+define hook-step
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+define hook-continue
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+define hook-nexti
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+define hook-next
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+define hook-finish
+set language c
+set *(int *)0xFA200014=simask_copy
+set language auto
+end
+
+
+Floating-point
+--------------
+
+The MPC860 and MPC821 do not have floating-point units. All code should
+get compiled with the appropriate -mcpu flag. The nof variants of the gcc
+runtime libraries should be used for linking.
+
+
+Miscellaneous
+-------------
+
+All development was based on the eth_comm port.
+
+
+Host System
+-----------
+
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+The port was developed on Pentiums II and III running RedHat Linux 6.0 and
+6.1. The following tools were used:
+
+ - GNU gcc snapshot dated 19991208 configured for powerpc-rtems;
+ - GNU binutils 2.9.1 configured for powerpc-rtems;
+
+Gcc 2.95.2 also worked. Gcc 2.95.1 will not compile the console driver with
+-O4 or -O3. Compile it manually with -O2.
+
+
+Known Problems
+--------------
+
+The cdtest will not run with interrupt-driven I/O. The reason is that the
+constructors for the static objects are called at boot time when the
+interrupts are still disabled. The output buffer fills up, but never empties,
+and the application goes into an infinite loop waiting for buffer space. This
+should have been documented in the rtems/c/src/tests/PROBLEMS file. The moral
+of this story is: do not do I/O from the constructors or destructors of static
+objects.
+
+The cpuuse and malloctest tests do not work properly, either with polled I/O
+or interrupt-driven I/O. They are known not to work with interrupt-driven I/O,
+but should work with polled I/O?
+
+Output stops prematurely in the termios test when the console is operating in
+interrupt-driven mode because the serial port is re-initialized before all
+characters in the last raw output buffer are sent. Adding calls to tcdrain()
+in the test task helps, but it does not solve the problem. What happens is
+that the CD2401 raises a transmit interrupt when the last character in the
+DMA buffer is written into the transmit FIFO, not when the last character
+has been transmitted. When tcdrain() returns, there might be up to 16
+characters in the output FIFO. The call to tcsetattr() causes the serial port
+to re-initialize, at which point the output FIFO is cleared. We could not find
+a way to detect whether characters are still in the FIFO and to wait for them
+to be transmitted.
+
+The first raw buffer to be transmitted after the console is re-initialized
+with tcsetattr() is garbled. At this time, it does not seem worth while to
+track this problem down.
+
+In the stackchk test, an access fault exception is raised after the stack is
+blown. This is one case were overwritting the first or last 16 bytes of the
+stack does cause problems (but hey, an exception occurred, which is better
+than propagating the error).
+
+In the stackchk test, an access fault exception is raised after the stack is
+blown. This is one case were overwritting the first or last 16 bytes of the
+stack does cause problems (but hey, an exception occurred, which is better
+than propagating the error).
+
+When using interrupt-driven I/O, psx08 produces all the expected output, but
+it does not return control to 167Bug. Is this test supposed to work with
+interrupt-driven console I/O?
+
+
+What's new
+----------
+
+All known problems with use of the caches on the MBX860-002 and MBX821-001
+have been resolved.
+
+
+Thanks
+------
+
+- to Jay Monkman (jmonkman@frasca.com) of Frasca International, Inc.
+ for his eth_comm port.
+
+- to On-Line Applications Research Corporation (OAR) for developing
+ RTEMS and making it available on a Technology Transfer basis;
+
+- to the FSF and to Cygnus Support for great free software;
+
+
+Test Configuration
+------------------
+
+Board: MBX821-001, MBX860-002
+CPU: Motorola MPC821, MPC860
+Clock Speed: 50 MHz, 40 MHz
+RAM: 4 MBytes of 32-bit DRAM
+Cache Configuration: Instruction cache on; data cache on, copyback mode.
+Times Reported in: clock ticks: TMBCLK = system clock / 16.
+Timer Source: Timebase clock
+GCC Flags: -O4 -fno-keep-inline-functions -mcpu=(821/860)
+Console: Operates in polled mode on SMC2. No I/O through EPPC-Bug.
+
+
+Test Results
+------------
+
+Single processor tests: All tests passed, except the following ones:
+
+ - paranoia required the FPSP and the default variants of libm (and libc and
+ libgcc) for us. It may work with the msoft-float variants for you, but it
+ does require the FPSP.
+
+ - cpuuse and malloctest did not work.
+
+ - The stackchk test got an access fault exception before the RTEMS stack
+ checker had had a chance to detect the corrupted stack.
+
+
+Multi-processort tests: not applicable -- No MPCI layer yet.
+
+
+Timing tests:
+ See the times-mbx821 and times-860 files for the results of the
+ timing tests.
+
+
+Network tests:
+ Network driver is being implemented.
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/bsp_specs b/c/src/lib/libbsp/powerpc/mbx8xx/bsp_specs
new file mode 100644
index 0000000000..8ec022948d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/bsp_specs
@@ -0,0 +1,26 @@
+%rename cpp old_cpp
+%rename lib old_lib
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*cpp:
+%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{qrtems: --start-group \
+%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
+%{qjava: -lffi -lgcjgc -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
+%{!qnolinkcmds: -T linkcmds%s}}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{qrtems: \
+%{!qrtems_debug: } \
+%{qrtems_debug: } ecrti%O%s}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/configure.in b/c/src/lib/libbsp/powerpc/mbx8xx/configure.in
new file mode 100644
index 0000000000..e87fa11590
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/configure.in
@@ -0,0 +1,36 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl $Id$
+
+AC_PREREQ(2.13)
+AC_INIT(bsp_specs)
+RTEMS_TOP(../../../../../..)
+AC_CONFIG_AUX_DIR(../../../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE(rtems-c-src-lib-libbsp-powerpc-mbx8xx,$RTEMS_VERSION,no)
+AM_MAINTAINER_MODE
+
+RTEMS_ENABLE_LIBCDIR
+RTEMS_ENABLE_MULTIPROCESSING
+RTEMS_ENABLE_NETWORKING
+
+RTEMS_ENV_RTEMSBSP
+RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
+RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
+RTEMS_CHECK_MULTIPROCESSING(RTEMS_BSP)
+RTEMS_CHECK_NETWORKING
+RTEMS_CANONICAL_HOST
+
+RTEMS_PROJECT_ROOT
+AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
+AM_CONDITIONAL(HAS_MP,test "$HAS_MP" = "yes")
+
+# Explicitly list a Makefile here
+AC_OUTPUT(
+Makefile
+console/Makefile
+include/Makefile
+network/Makefile
+startup/Makefile
+wrapup/Makefile)
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/console/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/console/Makefile.am
new file mode 100644
index 0000000000..82b58ef82e
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/console/Makefile.am
@@ -0,0 +1,32 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = $(ARCH)/console.rel
+
+C_FILES = console.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+OBJS = $(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(OBJS)
+ $(make-rel)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+
+all-local: $(ARCH) $(OBJS) $(PGM)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = console.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/console/console.c b/c/src/lib/libbsp/powerpc/mbx8xx/console/console.c
new file mode 100644
index 0000000000..c152d17321
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/console/console.c
@@ -0,0 +1,484 @@
+/*
+ * console.c
+ *
+ * This file contains the MBX8xx termios serial I/O package.
+ * Only asynchronous I/O is supported.
+ *
+ * The SCCs and SMCs are assigned as follows
+ *
+ * Channel Device Minor Note
+ * SMC1 /dev/tty0 0
+ * SMC2 /dev/tty1 1
+ * SCC1 2 N/A. Hardwired as ethernet port
+ * SCC2 /dev/tty2 3
+ * SCC3 /dev/tty3 4
+ * SCC4 /dev/tty4 5
+ *
+ * All ports support termios. All I/O is interrupt-driven, unless EPPCBug
+ * is used to do the I/O. To use EPPCBug, define the EPPCBUG_SMC1
+ * manifest constant in the configuration file (mbx8xx.cfg). EPPCBug I/O
+ * is currently limited to the EPPCBug debug console. This is a limitation
+ * of firmware revision 1.1. Later firmware should be able to do I/O
+ * through any port.This code assumes that the EPPCBug console is the
+ * default: SMC1.
+ *
+ * TO RUN THE TESTS, USE POLLED I/O THROUGH EPPCBUG. Some tests play with
+ * the interrupt masks and turn off I/O. Those tests will hang with when
+ * interrupt-driven I/O is used.
+ *
+ * Set CONSOLE_MINOR to the appropriate device minor number in the
+ * config file. This allows the RTEMS application console to be different
+ * from the EPPBug debug console or the GDB stup I/O port.
+ *
+ * This driver handles all five available serial ports: it distinguishes
+ * the sub-devices using minor device numbers. It is not possible to have
+ * other protocols running on the other ports when this driver is used as
+ * currently written.
+ *
+ * Based on code (alloc860.c in eth_comm port) by
+ * Jay Monkman (jmonkman@frasca.com),
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>.
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <bsp.h> /* Must be before libio.h */
+#include <rtems/libio.h>
+#include <termios.h>
+
+static int _EPPCBug_pollRead( int minor );
+static int _EPPCBug_pollWrite( int minor, const char *buf, int len );
+
+
+/*
+ * _EPPCBug_pollRead
+ *
+ * Read a character from the EPPCBug console, and return it. Return -1
+ * if there is no character in the input FIFO.
+ *
+ * Input parameters:
+ * minor - selected channel
+ *
+ * Output parameters: NONE
+ *
+ * Return value: char returned as positive signed int
+ * -1 if no character is present in the input FIFO.
+ */
+int _EPPCBug_pollRead(
+ int minor
+)
+{
+ extern volatile m8xx_t m8xx;
+
+ char c;
+ volatile int simask; /* We must read and write m8xx.simask */
+ int retval;
+ ISR_Level level;
+
+ struct {
+ int clun;
+ int dlun;
+ char * inbuf;
+ int nbytes_requested;
+ int reserved;
+ } volatile input_params;
+
+ struct {
+ int status;
+ union {
+ struct {
+ int input_char_available;
+ int output_possible;
+ int break_detected;
+ int modem_status;
+ } stat;
+ struct {
+ int nbytes_received;
+ } read;
+ } u;
+ } volatile output_params;
+
+ retval = -1;
+
+ /* Input through EPPCBug console */
+ input_params.clun = 0;
+ input_params.dlun = 0;
+ input_params.reserved = 0;
+
+ _ISR_Disable( level );
+ simask = m8xx.simask;
+
+ /* Check for a char in the input FIFO using .CIO_STAT */
+ asm volatile( "li 10,0x202
+ mr 3, %0
+ mr 4, %1
+ sc"
+ :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
+
+ if ( (output_params.status == 0) && output_params.u.stat.input_char_available) {
+
+ /* Read the char and return it */
+ input_params.inbuf = &c;
+ input_params.nbytes_requested = 1;
+
+ asm volatile( "li 10,0x200 /* Code for .CIO_READ */
+ mr 3, %0 /* Address of input_params */
+ mr 4, %1 /* Address of output_params */
+ sc" /* Call EPPCBUG */
+ :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
+
+ if ( (output_params.status == 0) && output_params.u.read.nbytes_received)
+ retval = (int)c;
+ }
+
+ m8xx.simask = simask;
+ _ISR_Enable( level );
+ return retval;
+}
+
+
+/*
+ * _EPPCBug_pollWrite
+ *
+ * Output buffer through EPPCBug. Returns only once every character has been
+ * sent (polled output).
+ *
+ * Input parameters:
+ * minor - selected channel
+ * buf - output buffer
+ * len - number of chars to output
+ *
+ * Output parameters: NONE
+ *
+ * Return value: IGNORED
+ */
+int _EPPCBug_pollWrite(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ extern volatile m8xx_t m8xx;
+
+ volatile int simask;
+ int i, retval;
+ ISR_Level level;
+
+ struct {
+ int clun;
+ int dlun;
+ const char * outbuf;
+ int nbytes_to_output;
+ int reserved;
+ } volatile input_params;
+
+ struct {
+ int status;
+ union {
+ struct {
+ int input_char_available;
+ int output_possible;
+ int break_detected;
+ int modem_status;
+ } stat;
+ struct {
+ int nbytes_sent;
+ } write;
+ } u;
+ } volatile output_params;
+
+ retval = -1;
+
+ /* Output through EPPCBug console */
+ input_params.clun = 0;
+ input_params.dlun = 0;
+ input_params.reserved = 0;
+
+ i = 0;
+
+ _ISR_Disable( level );
+ simask = m8xx.simask;
+
+ while (i < len) {
+ /* Wait for space in the output buffer */
+ do {
+ /* Check for space in the output FIFO */
+ asm volatile( "li 10,0x202 /* Code for .CIO_STAT */
+ mr 3, %0 /* Address of input_params */
+ mr 4, %1 /* Address of output_params */
+ sc" /* Call EPPCBUG */
+ :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
+
+ if (output_params.status)
+ goto error;
+ } while (!output_params.u.stat.output_possible);
+
+ /* Output the characters until done */
+ input_params.outbuf = &buf[i];
+ input_params.nbytes_to_output = len - i;
+
+ asm volatile( "li 10,0x201 /* Code for .CIO_WRITE */
+ mr 3, %0 /* Address of input_params */
+ mr 4, %1 /* Address of output_params */
+ sc" /* Call EPPCBUG */
+ :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
+
+ if (output_params.status)
+ goto error;
+
+ i += output_params.u.write.nbytes_sent;
+ }
+
+ /* Return something */
+ m8xx.simask = simask;
+ _ISR_Enable( level );
+ return RTEMS_SUCCESSFUL;
+
+error:
+ m8xx.simask = simask;
+ _ISR_Enable( level );
+ return -1;
+}
+
+
+/*
+ * Print functions: prototyped in bsp.h
+ * Debug printing on Channel 1
+ */
+
+void printk( char *fmt, ... )
+{
+ va_list ap; /* points to each unnamed argument in turn */
+ static char buf[256];
+ unsigned int level;
+
+ _CPU_ISR_Disable(level);
+
+ va_start(ap, fmt); /* make ap point to 1st unnamed arg */
+ vsprintf(buf, fmt, ap); /* send output to buffer */
+
+ BSP_output_string(buf); /* print buffer -- Channel 1 */
+
+ va_end(ap); /* clean up and re-enable interrupts */
+ _CPU_ISR_Enable(level);
+}
+
+
+void BSP_output_string( char * buf )
+{
+ int len = strlen(buf);
+ int minor; /* will be ignored */
+ rtems_status_code sc;
+
+ sc = _EPPCBug_pollWrite(minor, buf, len);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (sc);
+}
+
+
+/*
+ ***************
+ * BOILERPLATE *
+ ***************
+ *
+ * All these functions are prototyped in rtems/c/src/lib/include/console.h.
+ */
+
+/*
+ * Initialize and register the device
+ */
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize();
+
+ /*
+ * Do common initialization.
+ */
+ m8xx_uart_initialize();
+
+ /*
+ * Do device-specific initialization
+ */
+#ifndef EPPCBUG_SMC1
+ m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
+#endif /* EPPCBUG_SMC1 */
+
+ m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */
+ m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */
+
+#ifdef mpc860
+ m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */
+ m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */
+#endif /* mpc860 */
+
+ /*
+ * Set up interrupts
+ */
+ m8xx_uart_interrupts_initialize();
+
+ status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+ status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+ status = rtems_io_register_name ("/dev/tty2", major, SCC2_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+#ifdef mpc860
+ status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+ status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+#endif /* mpc860 */
+
+ /* Now register the RTEMS console */
+ status = rtems_io_register_name ("/dev/console", major, CONSOLE_MINOR);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred (status);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * Open the device
+ */
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ /* Used to track termios private data for callbacks */
+ extern struct rtems_termios_tty *ttyp[];
+
+ volatile m8xxSCCRegisters_t *sccregs;
+ rtems_status_code sc;
+ rtems_libio_open_close_args_t *args = arg;
+
+#ifdef EPPCBUG_SMC1
+ static const rtems_termios_callbacks sccEPPCBugCallbacks = {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ _EPPCBug_pollRead, /* pollRead */
+ _EPPCBug_pollWrite, /* write */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+ };
+#endif
+
+#ifdef UARTS_USE_INTERRUPTS
+ static const rtems_termios_callbacks intrCallbacks = {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ NULL, /* pollRead */
+ m8xx_uart_write, /* write */
+ m8xx_uart_setAttributes, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 1 /* outputUsesInterrupts */
+ };
+#else
+ static const rtems_termios_callbacks pollCallbacks = {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ m8xx_uart_pollRead, /* pollRead */
+ m8xx_uart_pollWrite, /* write */
+ m8xx_uart_setAttributes, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+ };
+#endif
+
+ if ( (minor < SMC1_MINOR) || (minor > NUM_PORTS-1) )
+ return RTEMS_INVALID_NUMBER;
+
+#ifdef EPPCBUG_SMC1
+ if (minor == SMC1_MINOR)
+ return rtems_termios_open (major, minor, arg, &sccEPPCBugCallbacks);
+#endif /* EPPCBUG_SMC1 */
+
+#ifdef UARTS_USE_INTERRUPTS
+ sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
+ ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */
+#else
+ sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
+#endif
+ return sc;
+}
+
+
+/*
+ * Close the device
+ */
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_close (arg);
+}
+
+
+/*
+ * Read from the device
+ */
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_read(arg);
+}
+
+
+/*
+ * Write to the device
+ */
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_write(arg);
+}
+
+
+/*
+ * Handle ioctl request.
+ */
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/include/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/include/Makefile.am
new file mode 100644
index 0000000000..ac0bb3566f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/include/Makefile.am
@@ -0,0 +1,23 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+H_FILES = bsp.h coverhd.h
+
+$(PROJECT_INCLUDE):
+ $(mkinstalldirs) $@
+
+$(PROJECT_INCLUDE)/bsp.h: bsp.h
+ $(INSTALL_DATA) $< $@
+
+$(PROJECT_INCLUDE)/coverhd.h: coverhd.h
+ $(INSTALL_DATA) $< $@
+
+PREINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp.h \
+ $(PROJECT_INCLUDE)/coverhd.h
+
+all-local: $(PREINSTALL_FILES)
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/include/bsp.h b/c/src/lib/libbsp/powerpc/mbx8xx/include/bsp.h
new file mode 100644
index 0000000000..df5d911fb0
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/include/bsp.h
@@ -0,0 +1,121 @@
+/* bsp.h
+ *
+ * This include file contains all board IO definitions.
+ *
+ * This file includes definitions for the MBX860 and MBX821.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __MBX8xx_h
+#define __MBX8xx_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <console.h>
+#include <clockdrv.h>
+#include <mpc8xx.h>
+#include <mpc8xx/cpm.h>
+#include <mpc8xx/mmu.h>
+#include <mpc8xx/console.h>
+
+/*
+ * Network driver configuration
+ */
+struct rtems_bsdnet_ifconfig;
+extern int rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config);
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "scc1"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_enet_driver_attach
+
+/*
+ * We need to decide how much memory will be non-cacheable. This
+ * will mainly be memory that will be used in DMA (network and serial
+ * buffers).
+ */
+#define NOCACHE_MEM_SIZE 512*1024
+
+/*
+ * Define the time limits for RTEMS Test Suite test durations.
+ * Long test and short test duration limits are provided. These
+ * values are in seconds and need to be converted to ticks for the
+ * application.
+ *
+ */
+
+#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
+#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
+
+/*
+ * Stuff for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 0
+
+#define Install_tm27_vector( handler ) set_vector( (handler), 0, 1 )
+
+#define Cause_tm27_intr()
+
+#define Clear_tm27_intr()
+
+#define Lower_tm27_intr()
+
+/* Constants -- THESE SHOULD BE DEFINED IN THE LINKER SCRIPT */
+
+#define RAM_START 0
+#define RAM_END 0x100000
+
+/* miscellaneous stuff assumed to exist */
+
+extern rtems_configuration_table BSP_Configuration;
+
+/*
+ * Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+/*
+ * How many libio files we want
+ */
+
+#define BSP_LIBIO_MAX_FDS 20
+
+/* functions */
+
+void bsp_cleanup( void );
+
+rtems_isr_entry set_vector( /* returns old vector */
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector, /* vector number */
+ int type /* RTEMS or RAW intr */
+);
+
+/*
+ * Debug print functions: implemented in console.c
+ */
+void printk( char *fmt, ... );
+void BSP_output_string( char * buf );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/include/coverhd.h b/c/src/lib/libbsp/powerpc/mbx8xx/include/coverhd.h
new file mode 100644
index 0000000000..37b2b3a5f1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/include/coverhd.h
@@ -0,0 +1,366 @@
+/* coverhd.h
+ *
+ * This include file has defines to represent the overhead associated
+ * with calling a particular directive from C. These are used in the
+ * Timing Test Suite to ignore the overhead required to pass arguments
+ * to directives. On some CPUs and/or target boards, this overhead
+ * is significant and makes it difficult to distinguish internal
+ * RTEMS execution time from that used to call the directive.
+ * This file should be updated after running the C overhead timing
+ * test. Once this update has been performed, the RTEMS Time Test
+ * Suite should be rebuilt to account for these overhead times in the
+ * timing results.
+ *
+ * NOTE: If these are all zero, then the times reported include
+ * all calling overhead including passing of arguments.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/targopts.h>
+
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+#if defined( INSTRUCTION_CACHE_ENABLE )
+/*
+ * 50 MHz processor, cache enabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
+#define CALLING_OVERHEAD_TASK_CREATE 1
+#define CALLING_OVERHEAD_TASK_IDENT 0
+#define CALLING_OVERHEAD_TASK_START 0
+#define CALLING_OVERHEAD_TASK_RESTART 0
+#define CALLING_OVERHEAD_TASK_DELETE 0
+#define CALLING_OVERHEAD_TASK_SUSPEND 0
+#define CALLING_OVERHEAD_TASK_RESUME 0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
+#define CALLING_OVERHEAD_TASK_MODE 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE 0
+#define CALLING_OVERHEAD_TASK_SET_NOTE 0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
+#define CALLING_OVERHEAD_CLOCK_GET 1
+#define CALLING_OVERHEAD_CLOCK_SET 1
+#define CALLING_OVERHEAD_CLOCK_TICK 0
+
+#define CALLING_OVERHEAD_TIMER_CREATE 0
+#define CALLING_OVERHEAD_TIMER_IDENT 0
+#define CALLING_OVERHEAD_TIMER_DELETE 0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1
+#define CALLING_OVERHEAD_TIMER_RESET 0
+#define CALLING_OVERHEAD_TIMER_CANCEL 0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
+
+#define CALLING_OVERHEAD_EVENT_SEND 0
+#define CALLING_OVERHEAD_EVENT_RECEIVE 0
+#define CALLING_OVERHEAD_SIGNAL_CATCH 0
+#define CALLING_OVERHEAD_SIGNAL_SEND 0
+#define CALLING_OVERHEAD_PARTITION_CREATE 1
+#define CALLING_OVERHEAD_PARTITION_IDENT 0
+#define CALLING_OVERHEAD_PARTITION_DELETE 0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
+#define CALLING_OVERHEAD_REGION_CREATE 1
+#define CALLING_OVERHEAD_REGION_IDENT 0
+#define CALLING_OVERHEAD_REGION_DELETE 0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
+#define CALLING_OVERHEAD_PORT_CREATE 0
+#define CALLING_OVERHEAD_PORT_IDENT 0
+#define CALLING_OVERHEAD_PORT_DELETE 0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE 0
+#define CALLING_OVERHEAD_IO_OPEN 0
+#define CALLING_OVERHEAD_IO_CLOSE 0
+#define CALLING_OVERHEAD_IO_READ 0
+#define CALLING_OVERHEAD_IO_WRITE 0
+#define CALLING_OVERHEAD_IO_CONTROL 0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
+
+#else
+/*
+ * 50 MHz processor, cache disabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 4
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 4
+#define CALLING_OVERHEAD_TASK_CREATE 7
+#define CALLING_OVERHEAD_TASK_IDENT 6
+#define CALLING_OVERHEAD_TASK_START 5
+#define CALLING_OVERHEAD_TASK_RESTART 5
+#define CALLING_OVERHEAD_TASK_DELETE 4
+#define CALLING_OVERHEAD_TASK_SUSPEND 4
+#define CALLING_OVERHEAD_TASK_RESUME 4
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY 5
+#define CALLING_OVERHEAD_TASK_MODE 5
+#define CALLING_OVERHEAD_TASK_GET_NOTE 5
+#define CALLING_OVERHEAD_TASK_SET_NOTE 5
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN 19
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 4
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 5
+#define CALLING_OVERHEAD_CLOCK_GET 20
+#define CALLING_OVERHEAD_CLOCK_SET 19
+#define CALLING_OVERHEAD_CLOCK_TICK 3
+
+#define CALLING_OVERHEAD_TIMER_CREATE 5
+#define CALLING_OVERHEAD_TIMER_IDENT 4
+#define CALLING_OVERHEAD_TIMER_DELETE 5
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 6
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 21
+#define CALLING_OVERHEAD_TIMER_RESET 4
+#define CALLING_OVERHEAD_TIMER_CANCEL 4
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE 6
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE 6
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 5
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 5
+
+#define CALLING_OVERHEAD_EVENT_SEND 5
+#define CALLING_OVERHEAD_EVENT_RECEIVE 5
+#define CALLING_OVERHEAD_SIGNAL_CATCH 4
+#define CALLING_OVERHEAD_SIGNAL_SEND 5
+#define CALLING_OVERHEAD_PARTITION_CREATE 7
+#define CALLING_OVERHEAD_PARTITION_IDENT 6
+#define CALLING_OVERHEAD_PARTITION_DELETE 4
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 5
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 5
+#define CALLING_OVERHEAD_REGION_CREATE 7
+#define CALLING_OVERHEAD_REGION_IDENT 5
+#define CALLING_OVERHEAD_REGION_DELETE 4
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT 6
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 5
+#define CALLING_OVERHEAD_PORT_CREATE 6
+#define CALLING_OVERHEAD_PORT_IDENT 5
+#define CALLING_OVERHEAD_PORT_DELETE 4
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 6
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 6
+
+#define CALLING_OVERHEAD_IO_INITIALIZE 6
+#define CALLING_OVERHEAD_IO_OPEN 6
+#define CALLING_OVERHEAD_IO_CLOSE 6
+#define CALLING_OVERHEAD_IO_READ 6
+#define CALLING_OVERHEAD_IO_WRITE 6
+#define CALLING_OVERHEAD_IO_CONTROL 6
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 5
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 3
+
+#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
+
+#else
+#if defined( INSTRUCTION_CACHE_ENABLE )
+/*
+ * 40 MHz processor, cache enabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1
+#define CALLING_OVERHEAD_TASK_CREATE 1
+#define CALLING_OVERHEAD_TASK_IDENT 0
+#define CALLING_OVERHEAD_TASK_START 0
+#define CALLING_OVERHEAD_TASK_RESTART 0
+#define CALLING_OVERHEAD_TASK_DELETE 0
+#define CALLING_OVERHEAD_TASK_SUSPEND 0
+#define CALLING_OVERHEAD_TASK_RESUME 0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
+#define CALLING_OVERHEAD_TASK_MODE 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE 0
+#define CALLING_OVERHEAD_TASK_SET_NOTE 0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
+#define CALLING_OVERHEAD_CLOCK_GET 1
+#define CALLING_OVERHEAD_CLOCK_SET 1
+#define CALLING_OVERHEAD_CLOCK_TICK 0
+
+#define CALLING_OVERHEAD_TIMER_CREATE 0
+#define CALLING_OVERHEAD_TIMER_IDENT 0
+#define CALLING_OVERHEAD_TIMER_DELETE 0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1
+#define CALLING_OVERHEAD_TIMER_RESET 0
+#define CALLING_OVERHEAD_TIMER_CANCEL 0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
+
+#define CALLING_OVERHEAD_EVENT_SEND 0
+#define CALLING_OVERHEAD_EVENT_RECEIVE 0
+#define CALLING_OVERHEAD_SIGNAL_CATCH 0
+#define CALLING_OVERHEAD_SIGNAL_SEND 0
+#define CALLING_OVERHEAD_PARTITION_CREATE 1
+#define CALLING_OVERHEAD_PARTITION_IDENT 0
+#define CALLING_OVERHEAD_PARTITION_DELETE 0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
+#define CALLING_OVERHEAD_REGION_CREATE 1
+#define CALLING_OVERHEAD_REGION_IDENT 0
+#define CALLING_OVERHEAD_REGION_DELETE 0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
+#define CALLING_OVERHEAD_PORT_CREATE 2
+#define CALLING_OVERHEAD_PORT_IDENT 0
+#define CALLING_OVERHEAD_PORT_DELETE 0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE 0
+#define CALLING_OVERHEAD_IO_OPEN 0
+#define CALLING_OVERHEAD_IO_CLOSE 0
+#define CALLING_OVERHEAD_IO_READ 0
+#define CALLING_OVERHEAD_IO_WRITE 0
+#define CALLING_OVERHEAD_IO_CONTROL 0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
+
+#else
+/*
+ * 40 MHz processor, cache disabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 4
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 3
+#define CALLING_OVERHEAD_TASK_CREATE 6
+#define CALLING_OVERHEAD_TASK_IDENT 5
+#define CALLING_OVERHEAD_TASK_START 5
+#define CALLING_OVERHEAD_TASK_RESTART 4
+#define CALLING_OVERHEAD_TASK_DELETE 4
+#define CALLING_OVERHEAD_TASK_SUSPEND 4
+#define CALLING_OVERHEAD_TASK_RESUME 4
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY 5
+#define CALLING_OVERHEAD_TASK_MODE 4
+#define CALLING_OVERHEAD_TASK_GET_NOTE 5
+#define CALLING_OVERHEAD_TASK_SET_NOTE 5
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN 17
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 3
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 5
+#define CALLING_OVERHEAD_CLOCK_GET 17
+#define CALLING_OVERHEAD_CLOCK_SET 17
+#define CALLING_OVERHEAD_CLOCK_TICK 3
+
+#define CALLING_OVERHEAD_TIMER_CREATE 4
+#define CALLING_OVERHEAD_TIMER_IDENT 4
+#define CALLING_OVERHEAD_TIMER_DELETE 5
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 5
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 19
+#define CALLING_OVERHEAD_TIMER_RESET 4
+#define CALLING_OVERHEAD_TIMER_CANCEL 4
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE 6
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE 5
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 5
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 4
+
+#define CALLING_OVERHEAD_EVENT_SEND 5
+#define CALLING_OVERHEAD_EVENT_RECEIVE 5
+#define CALLING_OVERHEAD_SIGNAL_CATCH 4
+#define CALLING_OVERHEAD_SIGNAL_SEND 4
+#define CALLING_OVERHEAD_PARTITION_CREATE 6
+#define CALLING_OVERHEAD_PARTITION_IDENT 5
+#define CALLING_OVERHEAD_PARTITION_DELETE 4
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 5
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 5
+#define CALLING_OVERHEAD_REGION_CREATE 6
+#define CALLING_OVERHEAD_REGION_IDENT 5
+#define CALLING_OVERHEAD_REGION_DELETE 4
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT 6
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 5
+#define CALLING_OVERHEAD_PORT_CREATE 6
+#define CALLING_OVERHEAD_PORT_IDENT 5
+#define CALLING_OVERHEAD_PORT_DELETE 4
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 5
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 5
+
+#define CALLING_OVERHEAD_IO_INITIALIZE 5
+#define CALLING_OVERHEAD_IO_OPEN 5
+#define CALLING_OVERHEAD_IO_CLOSE 5
+#define CALLING_OVERHEAD_IO_READ 5
+#define CALLING_OVERHEAD_IO_WRITE 5
+#define CALLING_OVERHEAD_IO_CONTROL 5
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 3
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 4
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 3
+
+#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/network/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/network/Makefile.am
new file mode 100644
index 0000000000..795c36566f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/network/Makefile.am
@@ -0,0 +1,36 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = $(ARCH)/network.rel
+
+C_FILES = network.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+OBJS = $(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
+
+$(PGM): $(OBJS)
+ $(make-rel)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+
+if HAS_NETWORKING
+all-local: $(ARCH) $(OBJS) $(PGM)
+endif
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = network.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/network/network.c b/c/src/lib/libbsp/powerpc/mbx8xx/network/network.c
new file mode 100644
index 0000000000..aaa477282f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/network/network.c
@@ -0,0 +1,1702 @@
+/*
+ * RTEMS/TCPIP driver for MPC8xx SCC1 Ethernet
+ *
+ * Modified for MPC860 by Jay Monkman (jmonkman@frasca.com)
+ *
+ * This supports Ethernet on either SCC1 or the FEC of the MPC860T.
+ * Right now, we only do 10 Mbps, even with the FEC. The function
+ * rtems_enet_driver_attach determines which one to use. Currently,
+ * only one may be used at a time.
+ *
+ * Based on the MC68360 network driver by
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * This supports ethernet on SCC1. Right now, we only do 10 Mbps.
+ *
+ * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * $Id$
+ */
+#include <bsp.h>
+#include <stdio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+/*
+ * Number of interfaces supported by this driver
+ */
+#define NIFACES 1
+
+/*
+ * Default number of buffer descriptors set aside for this driver.
+ * The number of transmit buffer descriptors has to be quite large
+ * since a single frame often uses four or more buffer descriptors.
+ */
+#define RX_BUF_COUNT 32
+#define TX_BUF_COUNT 8
+#define TX_BD_PER_BUF 4
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ * This must *not* be the same event used by the TCP/IP task synchronization.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * RTEMS event used to start transmit daemon.
+ * This must not be the same as INTERRUPT_EVENT.
+ */
+#define START_TRANSMIT_EVENT RTEMS_EVENT_2
+
+/*
+ * Receive buffer size -- Allow for a full ethernet packet plus CRC (1518).
+ * Round off to nearest multiple of RBUF_ALIGN.
+ */
+#define MAX_MTU_SIZE 1518
+#define RBUF_ALIGN 4
+#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
+
+#if (MCLBYTES < RBUF_SIZE)
+# error "Driver must have MCLBYTES > RBUF_SIZE"
+#endif
+
+extern unsigned32 simask_copy;
+
+/*
+ * Per-device data
+ */
+struct m8xx_enet_struct {
+ struct arpcom arpcom;
+ struct mbuf **rxMbuf;
+ struct mbuf **txMbuf;
+ int acceptBroadcast;
+ int rxBdCount;
+ int txBdCount;
+ int txBdHead;
+ int txBdTail;
+ int txBdActiveCount;
+ m8xxBufferDescriptor_t *rxBdBase;
+ m8xxBufferDescriptor_t *txBdBase;
+ rtems_id rxDaemonTid;
+ rtems_id txDaemonTid;
+
+ /*
+ * Statistics
+ */
+ unsigned long rxInterrupts;
+ unsigned long rxNotFirst;
+ unsigned long rxNotLast;
+ unsigned long rxGiant;
+ unsigned long rxNonOctet;
+ unsigned long rxRunt;
+ unsigned long rxBadCRC;
+ unsigned long rxOverrun;
+ unsigned long rxCollision;
+
+ unsigned long txInterrupts;
+ unsigned long txDeferred;
+ unsigned long txHeartbeat;
+ unsigned long txLateCollision;
+ unsigned long txRetryLimit;
+ unsigned long txUnderrun;
+ unsigned long txLostCarrier;
+ unsigned long txRawWait;
+};
+static struct m8xx_enet_struct enet_driver[NIFACES];
+
+
+/*
+ * SCC1 interrupt handler
+ */
+static rtems_isr
+m8xx_scc1_interrupt_handler (rtems_vector_number v)
+{
+ /* Frame received? */
+ if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) {
+ m8xx.scc1.scce = 0x8; /* Clear receive frame int */
+ m8xx.scc1.sccm &= ~0x8; /* Disable receive frame ints */
+ enet_driver[0].rxInterrupts++; /* Rx int has occurred */
+ rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+ }
+
+ /* Buffer transmitted or transmitter error? */
+ if ((m8xx.scc1.sccm & 0x12) && (m8xx.scc1.scce & 0x12)) {
+ m8xx.scc1.scce = 0x12; /* Clear Tx int */
+ m8xx.scc1.sccm &= ~0x12; /* Disable Tx ints */
+ enet_driver[0].txInterrupts++; /* Tx int has occurred */
+ rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+ }
+ m8xx.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
+}
+
+#ifdef MPC860T
+/*
+ * FEC interrupt handler
+ */
+static rtems_isr
+m860_fec_interrupt_handler (rtems_vector_number v)
+{
+ /*
+ * Frame received?
+ */
+ if (m8xx.fec.ievent & M8xx_FEC_IEVENT_RFINT) {
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
+ enet_driver[0].rxInterrupts++;
+ rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+ }
+
+ /*
+ * Buffer transmitted or transmitter error?
+ */
+ if (m8xx.fec.ievent & M8xx_FEC_IEVENT_TFINT) {
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
+ enet_driver[0].txInterrupts++;
+ rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+ }
+}
+#endif
+
+
+/*
+ * Initialize the ethernet hardware
+ */
+static void
+m8xx_enet_initialize (struct m8xx_enet_struct *sc)
+{
+ int i;
+ unsigned char *hwaddr;
+ rtems_status_code status;
+ rtems_isr_entry old_handler;
+
+ /*
+ * Configure port A
+ * PA15 is enet RxD. Set PAPAR(15) to 1, PADIR(15) to 0.
+ * PA14 is enet TxD. Set PAPAR(14) to 1, PADIR(14) to 0, PAODR(14) to 0.
+ * PA7 is input CLK1. Set PAPAR(7) to 1, PADIR(7) to 0.
+ * PA6 is input CLK2. Set PAPAR(6) to 1, PADIR(6) to 0.
+ */
+ m8xx.papar |= 0x303;
+ m8xx.padir &= ~0x303;
+ m8xx.paodr &= ~0x2;
+
+ /*
+ * Configure port C
+ * PC11 is CTS1*. Set PCPAR(11) to 0, PCDIR(11) to 0, and PCSO(11) to 1.
+ * PC10 is CD1*. Set PCPAR(10) to 0, PCDIR(10) to 0, and PCSO(10) to 1.
+ */
+ m8xx.pcpar &= ~0x30;
+ m8xx.pcdir &= ~0x30;
+ m8xx.pcso |= 0x30;
+
+ /*
+ * Connect CLK1 and CLK2 to SCC1 in the SICR.
+ * CLK1 is TxClk, CLK2 is RxClk. No grant mechanism, SCC1 is directly
+ * connected to the NMSI pins.
+ * R1CS = 0b101 (CLK2)
+ * T1CS = 0b100 (CLK1)
+ */
+ m8xx.sicr |= 0x2C;
+
+ /*
+ * Initialize SDMA configuration register
+ */
+ m8xx.sdcr = 1;
+
+ /*
+ * Allocate mbuf pointers
+ */
+ sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
+ M_MBUF, M_NOWAIT);
+ sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
+ M_MBUF, M_NOWAIT);
+ if (!sc->rxMbuf || !sc->txMbuf)
+ rtems_panic ("No memory for mbuf pointers");
+
+ /*
+ * Set receiver and transmitter buffer descriptor bases
+ */
+ sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+ sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+ m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
+ m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;
+
+ /*
+ * Send "Init parameters" command
+ */
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);
+
+ /*
+ * Set receive and transmit function codes
+ */
+ m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
+ m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
+
+ /*
+ * Set maximum receive buffer length
+ */
+ m8xx.scc1p.mrblr = RBUF_SIZE;
+
+ /*
+ * Set CRC parameters
+ */
+ m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
+ m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
+
+ /*
+ * Clear diagnostic counters
+ */
+ m8xx.scc1p.un.ethernet.crcec = 0;
+ m8xx.scc1p.un.ethernet.alec = 0;
+ m8xx.scc1p.un.ethernet.disfc = 0;
+
+ /*
+ * Set pad value
+ */
+ m8xx.scc1p.un.ethernet.pads = 0x8888;
+
+ /*
+ * Set retry limit
+ */
+ m8xx.scc1p.un.ethernet.ret_lim = 15;
+
+ /*
+ * Set maximum and minimum frame length
+ */
+ m8xx.scc1p.un.ethernet.mflr = 1518;
+ m8xx.scc1p.un.ethernet.minflr = 64;
+ m8xx.scc1p.un.ethernet.maxd1 = MAX_MTU_SIZE;
+ m8xx.scc1p.un.ethernet.maxd2 = MAX_MTU_SIZE;
+
+ /*
+ * Clear group address hash table
+ */
+ m8xx.scc1p.un.ethernet.gaddr1 = 0;
+ m8xx.scc1p.un.ethernet.gaddr2 = 0;
+ m8xx.scc1p.un.ethernet.gaddr3 = 0;
+ m8xx.scc1p.un.ethernet.gaddr4 = 0;
+
+ /*
+ * Set our physical address
+ */
+ hwaddr = sc->arpcom.ac_enaddr;
+
+ m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
+ m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
+ m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
+
+ /*
+ * Aggressive retry
+ */
+ m8xx.scc1p.un.ethernet.p_per = 0;
+
+ /*
+ * Clear individual address hash table
+ */
+ m8xx.scc1p.un.ethernet.iaddr1 = 0;
+ m8xx.scc1p.un.ethernet.iaddr2 = 0;
+ m8xx.scc1p.un.ethernet.iaddr3 = 0;
+ m8xx.scc1p.un.ethernet.iaddr4 = 0;
+
+ /*
+ * Clear temp address
+ */
+ m8xx.scc1p.un.ethernet.taddr_l = 0;
+ m8xx.scc1p.un.ethernet.taddr_m = 0;
+ m8xx.scc1p.un.ethernet.taddr_h = 0;
+
+ /*
+ * Set up receive buffer descriptors
+ */
+ for (i = 0 ; i < sc->rxBdCount ; i++) {
+ (sc->rxBdBase + i)->status = 0;
+ }
+
+ /*
+ * Set up transmit buffer descriptors
+ */
+ for (i = 0 ; i < sc->txBdCount ; i++) {
+ (sc->txBdBase + i)->status = 0;
+ sc->txMbuf[i] = NULL;
+ }
+ sc->txBdHead = sc->txBdTail = 0;
+ sc->txBdActiveCount = 0;
+
+ /*
+ * Clear any outstanding events
+ */
+ m8xx.scc1.scce = 0xFFFF;
+
+ /*
+ * Set up interrupts
+ */
+ status = rtems_interrupt_catch (m8xx_scc1_interrupt_handler,
+ PPC_IRQ_CPM_SCC1,
+ &old_handler);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_panic ("Can't attach M8xx SCC1 interrupt handler: %s\n",
+ rtems_status_text (status));
+ }
+ m8xx.scc1.sccm = 0; /* No interrupts unmasked till necessary */
+ m8xx.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
+
+ /*
+ * Set up General SCC Mode Register
+ * Ethernet configuration
+ */
+ m8xx.scc1.gsmr_h = 0x0;
+ m8xx.scc1.gsmr_l = 0x1088000c;
+
+ /*
+ * Set up data synchronization register
+ * Ethernet synchronization pattern
+ */
+ m8xx.scc1.dsr = 0xd555;
+
+ /*
+ * Set up protocol-specific mode register
+ * No Heartbeat check
+ * No force collision
+ * Discard short frames
+ * Individual address mode
+ * Ethernet CRC
+ * Not promisuous
+ * Ignore/accept broadcast packets as specified
+ * Normal backoff timer
+ * No loopback
+ * No input sample at end of frame
+ * 64-byte limit for late collision
+ * Wait 22 bits before looking for start of frame delimiter
+ * Disable full-duplex operation
+ */
+ m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
+
+ /*
+ * Enable the TENA (RTS1*) pin
+ */
+ m8xx.pcpar |= 0x1;
+ m8xx.pcdir &= ~0x1;
+
+
+ /*
+ * Set up interrupts
+ * FIXME: DANGER: WARNING:
+ * CICR and SIMASK must be set in any module that uses
+ * the CPM. Currently those are console-generic.c and
+ * network.c. If the registers are not set the same
+ * in both places, strange things may happen.
+ * If they are only set in one place, then an application
+ * that uses only the other module won't work correctly.
+ * Put this comment in each module that sets these 2 registers
+ */
+#ifdef mpc860
+ m8xx.cicr = 0x00e43f80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
+ SCdP=SCC4, IRL=1, HP=PC15, IEN=1 */
+#else
+ m8xx.cicr = 0x00043F80; /* SCaP=SCC1, SCbP=SCC2, IRL=1, HP=PC15, IEN=1 */
+#endif
+ simask_copy = m8xx.simask | M8xx_SIMASK_LVM1; /* Enable level interrupts */
+ m8xx.simask |= M8xx_SIMASK_LVM1; /* Enable level interrupts */
+
+ /*
+ * Enable receiver and transmitter
+ */
+ m8xx.scc1.gsmr_l = 0x1088003c;
+}
+
+
+#ifdef MPC860T
+static void
+m860_fec_initialize_hardware (struct m860_enet_struct *sc)
+{
+ int i;
+ unsigned char *hwaddr;
+ rtems_status_code status;
+ rtems_isr_entry old_handler;
+
+ /*
+ * Issue reset to FEC
+ */
+ m8xx.fec.ecntrl=0x1;
+
+ /*
+ * Put ethernet transciever in reset
+ */
+ m8xx.pgcra |= 0x80;
+
+ /*
+ * Configure I/O ports
+ */
+ m8xx.pdpar = 0x1fff;
+ m8xx.pddir = 0x1c58;
+
+ /*
+ * Take ethernet transciever out of reset
+ */
+ m8xx.pgcra &= ~0x80;
+
+
+ /*
+ * Set SIU interrupt level to LVL2
+ *
+ */
+ m8xx.fec.ivec = 0x02 << 29;
+
+ /*
+ * Set the TX and RX fifo sizes. For now, we'll split it evenly
+ */
+ /* If you uncomment these, the FEC will not work right.
+ m8xx.fec.r_fstart = ((m8xx.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
+ m8xx.fec.x_fstart = 0;
+ */
+
+ /*
+ * Set our physical address
+ */
+ hwaddr = sc->arpcom.ac_enaddr;
+
+ m8xx.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
+ (hwaddr[2] << 8) | (hwaddr[3] << 0);
+ m8xx.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
+
+ /*
+ * Clear the hash table
+ */
+ m8xx.fec.hash_table_high = 0;
+ m8xx.fec.hash_table_low = 0;
+
+ /*
+ * Set up receive buffer size
+ */
+ m8xx.fec.r_buf_size = 0x5f0; /* set to 1520 */
+
+ /*
+ * Allocate mbuf pointers
+ */
+ sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
+ M_MBUF, M_NOWAIT);
+ sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
+ M_MBUF, M_NOWAIT);
+ if (!sc->rxMbuf || !sc->txMbuf)
+ rtems_panic ("No memory for mbuf pointers");
+
+ /*
+ * Set receiver and transmitter buffer descriptor bases
+ */
+ sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+ sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+ m8xx.fec.r_des_start = (int)sc->rxBdBase;
+ m8xx.fec.x_des_start = (int)sc->txBdBase;
+
+ /*
+ * Set up Receive Control Register:
+ * Not promiscuous mode
+ * MII mode
+ * Half duplex
+ * No loopback
+ */
+ m8xx.fec.r_cntrl = 0x00000006;
+
+ /*
+ * Set up Transmit Control Register:
+ * Half duplex
+ * No heartbeat
+ */
+ m8xx.fec.x_cntrl = 0x00000000;
+
+ /*
+ * Set up DMA function code:
+ * Big-endian
+ * DMA functino code = 0
+ */
+ m8xx.fec.fun_code = 0x78000000;
+
+ /*
+ * Initialize SDMA configuration register
+ * SDMA ignores FRZ
+ * FEC not aggressive
+ * FEC arbitration ID = 0 => U-bus arbitration = 6
+ * RISC arbitration ID = 1 => U-bus arbitration = 5
+ */
+ m8xx.sdcr = 1;
+
+ /*
+ * Set MII speed to 2.5 MHz for 25 Mhz system clock
+ */
+ m8xx.fec.mii_speed = 0x0a;
+ m8xx.fec.mii_data = 0x58021000;
+
+ /*
+ * Set up receive buffer descriptors
+ */
+ for (i = 0 ; i < sc->rxBdCount ; i++)
+ (sc->rxBdBase + i)->status = 0;
+
+ /*
+ * Set up transmit buffer descriptors
+ */
+ for (i = 0 ; i < sc->txBdCount ; i++) {
+ (sc->txBdBase + i)->status = 0;
+ sc->txMbuf[i] = NULL;
+ }
+ sc->txBdHead = sc->txBdTail = 0;
+ sc->txBdActiveCount = 0;
+
+
+
+ /*
+ * Mask all FEC interrupts and clear events
+ */
+ m8xx.fec.imask = M8xx_FEC_IEVENT_TFINT |
+ M8xx_FEC_IEVENT_RFINT;
+ m8xx.fec.ievent = ~0;
+
+ /*
+ * Set up interrupts
+ */
+ status = rtems_interrupt_catch (m860_fec_interrupt_handler,
+ PPC_IRQ_LVL2,
+ &old_handler);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't attach M860 FEC interrupt handler: %s\n",
+ rtems_status_text (status));
+
+}
+#endif
+
+
+/*
+ * Soak up buffer descriptors that have been sent.
+ * Note that a buffer descriptor can't be retired as soon as it becomes
+ * ready. The MPC860 manual (MPC860UM/AD 07/98 Rev.1) and the MPC821
+ * manual state that, "If an Ethernet frame is made up of multiple
+ * buffers, the user should not reuse the first buffer descriptor until
+ * the last buffer descriptor of the frame has had its ready bit cleared
+ * by the CPM".
+ */
+static void
+m8xx_Enet_retire_tx_bd (struct m8xx_enet_struct *sc)
+{
+ rtems_unsigned16 status;
+ int i;
+ int nRetired;
+ struct mbuf *m, *n;
+
+ i = sc->txBdTail;
+ nRetired = 0;
+ while ((sc->txBdActiveCount != 0)
+ && (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
+ /*
+ * See if anything went wrong
+ */
+ if (status & (M8xx_BD_DEFER |
+ M8xx_BD_HEARTBEAT |
+ M8xx_BD_LATE_COLLISION |
+ M8xx_BD_RETRY_LIMIT |
+ M8xx_BD_UNDERRUN |
+ M8xx_BD_CARRIER_LOST)) {
+ /*
+ * Check for errors which stop the transmitter.
+ */
+ if (status & (M8xx_BD_LATE_COLLISION |
+ M8xx_BD_RETRY_LIMIT |
+ M8xx_BD_UNDERRUN)) {
+ if (status & M8xx_BD_LATE_COLLISION)
+ enet_driver[0].txLateCollision++;
+ if (status & M8xx_BD_RETRY_LIMIT)
+ enet_driver[0].txRetryLimit++;
+ if (status & M8xx_BD_UNDERRUN)
+ enet_driver[0].txUnderrun++;
+
+ /*
+ * Restart the transmitter
+ */
+ /* FIXME: this should get executed only if using the SCC */
+ m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
+ }
+ if (status & M8xx_BD_DEFER)
+ enet_driver[0].txDeferred++;
+ if (status & M8xx_BD_HEARTBEAT)
+ enet_driver[0].txHeartbeat++;
+ if (status & M8xx_BD_CARRIER_LOST)
+ enet_driver[0].txLostCarrier++;
+ }
+ nRetired++;
+ if (status & M8xx_BD_LAST) {
+ /*
+ * A full frame has been transmitted.
+ * Free all the associated buffer descriptors.
+ */
+ sc->txBdActiveCount -= nRetired;
+ while (nRetired) {
+ nRetired--;
+ m = sc->txMbuf[sc->txBdTail];
+ MFREE (m, n);
+ if (++sc->txBdTail == sc->txBdCount)
+ sc->txBdTail = 0;
+ }
+ }
+ if (++i == sc->txBdCount)
+ i = 0;
+ }
+}
+
+/*
+ * reader task
+ */
+static void
+scc_rxDaemon (void *arg)
+{
+ struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_unsigned16 status;
+ m8xxBufferDescriptor_t *rxBd;
+ int rxBdIndex;
+
+ /*
+ * Allocate space for incoming packets and start reception
+ */
+ for (rxBdIndex = 0 ; ;) {
+ rxBd = sc->rxBdBase + rxBdIndex;
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+ sc->rxMbuf[rxBdIndex] = m;
+ rxBd->buffer = mtod (m, void *);
+ rxBd->status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
+ if (++rxBdIndex == sc->rxBdCount) {
+ rxBd->status |= M8xx_BD_WRAP;
+ break;
+ }
+ }
+
+ /*
+ * Input packet handling loop
+ */
+ rxBdIndex = 0;
+ for (;;) {
+ rxBd = sc->rxBdBase + rxBdIndex;
+
+ /*
+ * Wait for packet if there's not one ready
+ */
+ if ((status = rxBd->status) & M8xx_BD_EMPTY) {
+ /*
+ * Clear old events
+ */
+ m8xx.scc1.scce = 0x8;
+
+ /*
+ * Wait for packet
+ * Note that the buffer descriptor is checked
+ * *before* the event wait -- this catches the
+ * possibility that a packet arrived between the
+ * `if' above, and the clearing of the event register.
+ */
+ while ((status = rxBd->status) & M8xx_BD_EMPTY) {
+ rtems_event_set events;
+
+ /*
+ * Unmask RXF (Full frame received) event
+ */
+ m8xx.scc1.sccm |= 0x8;
+
+ rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+ }
+ }
+
+ /*
+ * Check that packet is valid
+ */
+ if ((status & (M8xx_BD_LAST |
+ M8xx_BD_FIRST_IN_FRAME |
+ M8xx_BD_LONG |
+ M8xx_BD_NONALIGNED |
+ M8xx_BD_SHORT |
+ M8xx_BD_CRC_ERROR |
+ M8xx_BD_OVERRUN |
+ M8xx_BD_COLLISION)) ==
+ (M8xx_BD_LAST |
+ M8xx_BD_FIRST_IN_FRAME)) {
+ /*
+ * Pass the packet up the chain.
+ * FIXME: Packet filtering hook could be done here.
+ */
+ struct ether_header *eh;
+
+ /*
+ * Invalidate the buffer for this descriptor
+ */
+ rtems_invalidate_multiple_data_cache_lines(rxBd->buffer, rxBd->length);
+
+ m = sc->rxMbuf[rxBdIndex];
+ m->m_len = m->m_pkthdr.len = rxBd->length -
+ sizeof(rtems_unsigned32) -
+ sizeof(struct ether_header);
+ eh = mtod (m, struct ether_header *);
+ m->m_data += sizeof(struct ether_header);
+ ether_input (ifp, eh, m);
+
+ /*
+ * Allocate a new mbuf
+ */
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+ sc->rxMbuf[rxBdIndex] = m;
+ rxBd->buffer = mtod (m, void *);
+ }
+ else {
+ /*
+ * Something went wrong with the reception
+ */
+ if (!(status & M8xx_BD_LAST))
+ sc->rxNotLast++;
+ if (!(status & M8xx_BD_FIRST_IN_FRAME))
+ sc->rxNotFirst++;
+ if (status & M8xx_BD_LONG)
+ sc->rxGiant++;
+ if (status & M8xx_BD_NONALIGNED)
+ sc->rxNonOctet++;
+ if (status & M8xx_BD_SHORT)
+ sc->rxRunt++;
+ if (status & M8xx_BD_CRC_ERROR)
+ sc->rxBadCRC++;
+ if (status & M8xx_BD_OVERRUN)
+ sc->rxOverrun++;
+ if (status & M8xx_BD_COLLISION)
+ sc->rxCollision++;
+ }
+
+ /*
+ * Reenable the buffer descriptor
+ */
+ rxBd->status = (status & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) |
+ M8xx_BD_EMPTY;
+
+ /*
+ * Move to next buffer descriptor
+ */
+ if (++rxBdIndex == sc->rxBdCount)
+ rxBdIndex = 0;
+ }
+}
+
+
+#ifdef MPC860T
+static void
+fec_rxDaemon (void *arg)
+{
+ struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_unsigned16 status;
+ m8xxBufferDescriptor_t *rxBd;
+ int rxBdIndex;
+
+ /*
+ * Allocate space for incoming packets and start reception
+ */
+ for (rxBdIndex = 0 ; ;) {
+ rxBd = sc->rxBdBase + rxBdIndex;
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+ sc->rxMbuf[rxBdIndex] = m;
+ rxBd->buffer = mtod (m, void *);
+ rxBd->status = M8xx_BD_EMPTY;
+ m8xx.fec.r_des_active = 0x1000000;
+ if (++rxBdIndex == sc->rxBdCount) {
+ rxBd->status |= M8xx_BD_WRAP;
+ break;
+ }
+ }
+
+ /*
+ * Input packet handling loop
+ */
+ rxBdIndex = 0;
+ for (;;) {
+ rxBd = sc->rxBdBase + rxBdIndex;
+
+ /*
+ * Wait for packet if there's not one ready
+ */
+ if ((status = rxBd->status) & M8xx_BD_EMPTY) {
+ /*
+ * Clear old events
+ */
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
+
+ /*
+ * Wait for packet
+ * Note that the buffer descriptor is checked
+ * *before* the event wait -- this catches the
+ * possibility that a packet arrived between the
+ * `if' above, and the clearing of the event register.
+ */
+ while ((status = rxBd->status) & M8xx_BD_EMPTY) {
+ rtems_event_set events;
+
+ /*
+ * Unmask RXF (Full frame received) event
+ */
+ m8xx.fec.ievent |= M8xx_FEC_IEVENT_RFINT;
+
+ rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+ }
+ }
+
+ /*
+ * Check that packet is valid
+ */
+ if (status & M8xx_BD_LAST) {
+ /*
+ * Pass the packet up the chain.
+ * FIXME: Packet filtering hook could be done here.
+ */
+ struct ether_header *eh;
+
+ /*
+ * Invalidate the buffer for this descriptor
+ */
+ rtems_invalidate_multiple_data_cache_lines(rxBd->buffer, rxBd->length);
+
+ m = sc->rxMbuf[rxBdIndex];
+ m->m_len = m->m_pkthdr.len = rxBd->length -
+ sizeof(rtems_unsigned32) -
+ sizeof(struct ether_header);
+ eh = mtod (m, struct ether_header *);
+ m->m_data += sizeof(struct ether_header);
+ ether_input (ifp, eh, m);
+
+ /*
+ * Allocate a new mbuf
+ */
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+ sc->rxMbuf[rxBdIndex] = m;
+ rxBd->buffer = mtod (m, void *);
+ }
+ else {
+ /*
+ * Something went wrong with the reception
+ */
+ if (!(status & M8xx_BD_LAST))
+ sc->rxNotLast++;
+ if (status & M8xx_BD_LONG)
+ sc->rxGiant++;
+ if (status & M8xx_BD_NONALIGNED)
+ sc->rxNonOctet++;
+ if (status & M8xx_BD_SHORT)
+ sc->rxRunt++;
+ if (status & M8xx_BD_CRC_ERROR)
+ sc->rxBadCRC++;
+ if (status & M8xx_BD_OVERRUN)
+ sc->rxOverrun++;
+ if (status & M8xx_BD_COLLISION)
+ sc->rxCollision++;
+ }
+ /*
+ * Reenable the buffer descriptor
+ */
+ rxBd->status = (status & M8xx_BD_WRAP) |
+ M8xx_BD_EMPTY;
+ m8xx.fec.r_des_active = 0x1000000;
+ /*
+ * Move to next buffer descriptor
+ */
+ if (++rxBdIndex == sc->rxBdCount)
+ rxBdIndex = 0;
+ }
+}
+#endif
+
+
+static void
+scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+ struct m8xx_enet_struct *sc = ifp->if_softc;
+ volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
+ struct mbuf *l = NULL;
+ rtems_unsigned16 status;
+ int nAdded;
+
+ /*
+ * Free up buffer descriptors
+ */
+ m8xx_Enet_retire_tx_bd (sc);
+
+ /*
+ * Set up the transmit buffer descriptors.
+ * No need to pad out short packets since the
+ * hardware takes care of that automatically.
+ * No need to copy the packet to a contiguous buffer
+ * since the hardware is capable of scatter/gather DMA.
+ */
+ nAdded = 0;
+ txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+ for (;;) {
+ /*
+ * Wait for buffer descriptor to become available.
+ */
+ if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+ /*
+ * Clear old events
+ */
+ m8xx.scc1.scce = 0x12;
+
+ /*
+ * Wait for buffer descriptor to become available.
+ * Note that the buffer descriptors are checked
+ * *before* * entering the wait loop -- this catches
+ * the possibility that a buffer descriptor became
+ * available between the `if' above, and the clearing
+ * of the event register.
+ * This is to catch the case where the transmitter
+ * stops in the middle of a frame -- and only the
+ * last buffer descriptor in a frame can generate
+ * an interrupt.
+ */
+ m8xx_Enet_retire_tx_bd (sc);
+ while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+ rtems_event_set events;
+
+ /*
+ * Unmask TXB (buffer transmitted) and
+ * TXE (transmitter error) events.
+ */
+ m8xx.scc1.sccm |= 0x12;
+ rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+ m8xx_Enet_retire_tx_bd (sc);
+ }
+ }
+
+ /*
+ * Don't set the READY flag till the
+ * whole packet has been readied.
+ */
+ status = nAdded ? M8xx_BD_READY : 0;
+
+ /*
+ * FIXME: Why not deal with empty mbufs at at higher level?
+ * The IP fragmentation routine in ip_output
+ * can produce packet fragments with zero length.
+ * I think that ip_output should be changed to get
+ * rid of these zero-length mbufs, but for now,
+ * I'll deal with them here.
+ */
+ if (m->m_len) {
+ /*
+ * Fill in the buffer descriptor
+ */
+ txBd->buffer = mtod (m, void *);
+ txBd->length = m->m_len;
+
+ /*
+ * Flush the buffer for this descriptor
+ */
+ rtems_flush_multiple_data_cache_lines(txBd->buffer, txBd->length);
+
+ sc->txMbuf[sc->txBdHead] = m;
+ nAdded++;
+ if (++sc->txBdHead == sc->txBdCount) {
+ status |= M8xx_BD_WRAP;
+ sc->txBdHead = 0;
+ }
+ l = m;
+ m = m->m_next;
+ }
+ else {
+ /*
+ * Just toss empty mbufs
+ */
+ struct mbuf *n;
+ MFREE (m, n);
+ m = n;
+ if (l != NULL)
+ l->m_next = m;
+ }
+
+ /*
+ * Set the transmit buffer status.
+ * Break out of the loop if this mbuf is the last in the frame.
+ */
+ if (m == NULL) {
+ if (nAdded) {
+ status |= M8xx_BD_PAD | M8xx_BD_LAST | M8xx_BD_TX_CRC | M8xx_BD_INTERRUPT;
+ txBd->status = status;
+ firstTxBd->status |= M8xx_BD_READY;
+ sc->txBdActiveCount += nAdded;
+ }
+ break;
+ }
+ txBd->status = status;
+ txBd = sc->txBdBase + sc->txBdHead;
+ }
+}
+
+
+#ifdef MPC860T
+static void
+fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+ struct m8xx_enet_struct *sc = ifp->if_softc;
+ volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
+ /* struct mbuf *l = NULL; */
+ rtems_unsigned16 status;
+ int nAdded;
+
+ /*
+ * Free up buffer descriptors
+ */
+ m8xx_Enet_retire_tx_bd (sc);
+
+ /*
+ * Set up the transmit buffer descriptors.
+ * No need to pad out short packets since the
+ * hardware takes care of that automatically.
+ * No need to copy the packet to a contiguous buffer
+ * since the hardware is capable of scatter/gather DMA.
+ */
+ nAdded = 0;
+ txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+ for (;;) {
+ /*
+ * Wait for buffer descriptor to become available.
+ */
+ if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+ /*
+ * Clear old events
+ */
+ m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
+
+ /*
+ * Wait for buffer descriptor to become available.
+ * Note that the buffer descriptors are checked
+ * *before* * entering the wait loop -- this catches
+ * the possibility that a buffer descriptor became
+ * available between the `if' above, and the clearing
+ * of the event register.
+ * This is to catch the case where the transmitter
+ * stops in the middle of a frame -- and only the
+ * last buffer descriptor in a frame can generate
+ * an interrupt.
+ */
+ m8xx_Enet_retire_tx_bd (sc);
+ while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+ rtems_event_set events;
+
+ /*
+ * Unmask TXB (buffer transmitted) and
+ * TXE (transmitter error) events.
+ */
+ m8xx.fec.ievent |= M8xx_FEC_IEVENT_TFINT;
+ rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+ m8xx_Enet_retire_tx_bd (sc);
+ }
+ }
+
+ /*
+ * Don't set the READY flag till the
+ * whole packet has been readied.
+ */
+ status = nAdded ? M8xx_BD_READY : 0;
+
+ /*
+ * FIXME: Why not deal with empty mbufs at at higher level?
+ * The IP fragmentation routine in ip_output
+ * can produce packet fragments with zero length.
+ * I think that ip_output should be changed to get
+ * rid of these zero-length mbufs, but for now,
+ * I'll deal with them here.
+ */
+ if (m->m_len) {
+ /*
+ * Fill in the buffer descriptor
+ */
+ txBd->buffer = mtod (m, void *);
+ txBd->length = m->m_len;
+
+ /*
+ * Flush the buffer for this descriptor
+ */
+ rtems_flush_multiple_data_cache_lines(txBd->buffer, txBd->length);
+
+ sc->txMbuf[sc->txBdHead] = m;
+ nAdded++;
+ if (++sc->txBdHead == sc->txBdCount) {
+ status |= M8xx_BD_WRAP;
+ sc->txBdHead = 0;
+ }
+ /* l = m;*/
+ m = m->m_next;
+ }
+ else {
+ /*
+ * Just toss empty mbufs
+ */
+ struct mbuf *n;
+ MFREE (m, n);
+ m = n;
+ /*
+ if (l != NULL)
+ l->m_next = m;
+ */
+ }
+
+ /*
+ * Set the transmit buffer status.
+ * Break out of the loop if this mbuf is the last in the frame.
+ */
+ if (m == NULL) {
+ if (nAdded) {
+ status |= M8xx_BD_LAST | M8xx_BD_TX_CRC;
+ txBd->status = status;
+ firstTxBd->status |= M8xx_BD_READY;
+ m8xx.fec.x_des_active = 0x1000000;
+ sc->txBdActiveCount += nAdded;
+ }
+ break;
+ }
+ txBd->status = status;
+ txBd = sc->txBdBase + sc->txBdHead;
+ }
+}
+#endif
+
+
+/*
+ * Driver transmit daemon
+ */
+void
+scc_txDaemon (void *arg)
+{
+ struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_event_set events;
+
+ for (;;) {
+ /*
+ * Wait for packet
+ */
+ rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
+
+ /*
+ * Send packets till queue is empty
+ */
+ for (;;) {
+ /*
+ * Get the next mbuf chain to transmit.
+ */
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (!m)
+ break;
+ scc_sendpacket (ifp, m);
+ }
+ ifp->if_flags &= ~IFF_OACTIVE;
+ }
+}
+
+
+#ifdef MPC860T
+void
+fec_txDaemon (void *arg)
+{
+ struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_event_set events;
+
+ for (;;) {
+ /*
+ * Wait for packet
+ */
+ rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events);
+
+ /*
+ * Send packets till queue is empty
+ */
+ for (;;) {
+ /*
+ * Get the next mbuf chain to transmit.
+ */
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (!m)
+ break;
+ fec_sendpacket (ifp, m);
+ }
+ ifp->if_flags &= ~IFF_OACTIVE;
+ }
+}
+#endif
+
+
+/*
+ * Send packet (caller provides header).
+ */
+static void
+m8xx_enet_start (struct ifnet *ifp)
+{
+ struct m8xx_enet_struct *sc = ifp->if_softc;
+
+ rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
+ ifp->if_flags |= IFF_OACTIVE;
+}
+
+
+/*
+ * Initialize and start the device
+ */
+static void
+scc_init (void *arg)
+{
+ struct m8xx_enet_struct *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ if (sc->txDaemonTid == 0) {
+
+ /*
+ * Set up SCC hardware
+ */
+ m8xx_enet_initialize (sc);
+
+ /*
+ * Start driver tasks
+ */
+ sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, scc_txDaemon, sc);
+ sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, scc_rxDaemon, sc);
+
+ }
+
+ /*
+ * Set flags appropriately
+ */
+ if (ifp->if_flags & IFF_PROMISC)
+ m8xx.scc1.psmr |= 0x200;
+ else
+ m8xx.scc1.psmr &= ~0x200;
+
+ /*
+ * Tell the world that we're running.
+ */
+ ifp->if_flags |= IFF_RUNNING;
+
+ /*
+ * Enable receiver and transmitter
+ */
+ m8xx.scc1.gsmr_l |= 0x30;
+}
+
+
+#ifdef MPC860T
+static void
+fec_init (void *arg)
+{
+ struct m8xx_enet_struct *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ if (sc->txDaemonTid == 0) {
+
+ /*
+ * Set up SCC hardware
+ */
+ m8xx_fec_initialize_hardware (sc);
+
+ /*
+ * Start driver tasks
+ */
+ sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, fec_txDaemon, sc);
+ sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, fec_rxDaemon, sc);
+
+ }
+
+ /*
+ * Set flags appropriately
+ */
+ if (ifp->if_flags & IFF_PROMISC)
+ m8xx.fec.r_cntrl |= 0x8;
+ else
+ m8xx.fec.r_cntrl &= ~0x8;
+
+
+ /*
+ * Tell the world that we're running.
+ */
+ ifp->if_flags |= IFF_RUNNING;
+
+ /*
+ * Enable receiver and transmitter
+ */
+ m8xx.fec.ecntrl = 0x2;
+}
+#endif
+
+
+/*
+ * Stop the device
+ */
+static void
+scc_stop (struct m8xx_enet_struct *sc)
+{
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+
+ /*
+ * Shut down receiver and transmitter
+ */
+ m8xx.scc1.gsmr_l &= ~0x30;
+}
+
+
+#ifdef MPC860T
+static void
+fec_stop (struct m8xx_enet_struct *sc)
+{
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+
+ /*
+ * Shut down receiver and transmitter
+ */
+ m8xx.fec.ecntrl = 0x0;
+}
+#endif
+
+
+/*
+ * Show interface statistics
+ */
+static void
+enet_stats (struct m8xx_enet_struct *sc)
+{
+ printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
+ printf (" Not First:%-8lu", sc->rxNotFirst);
+ printf (" Not Last:%-8lu\n", sc->rxNotLast);
+ printf (" Giant:%-8lu", sc->rxGiant);
+ printf (" Runt:%-8lu", sc->rxRunt);
+ printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
+ printf (" Bad CRC:%-8lu", sc->rxBadCRC);
+ printf (" Overrun:%-8lu", sc->rxOverrun);
+ printf (" Collision:%-8lu\n", sc->rxCollision);
+ printf (" Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);
+
+ printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
+ printf (" Deferred:%-8lu", sc->txDeferred);
+ printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
+ printf (" No Carrier:%-8lu", sc->txLostCarrier);
+ printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
+ printf (" Late Collision:%-8lu\n", sc->txLateCollision);
+ printf (" Underrun:%-8lu", sc->txUnderrun);
+ printf (" Raw output wait:%-8lu\n", sc->txRawWait);
+}
+
+
+/*
+ * Driver ioctl handler
+ */
+static int
+scc_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+ struct m8xx_enet_struct *sc = ifp->if_softc;
+ int error = 0;
+
+ switch (command) {
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ ether_ioctl (ifp, command, data);
+ break;
+
+ case SIOCSIFFLAGS:
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+ case IFF_RUNNING:
+ scc_stop (sc);
+ break;
+
+ case IFF_UP:
+ scc_init (sc);
+ break;
+
+ case IFF_UP | IFF_RUNNING:
+ scc_stop (sc);
+ scc_init (sc);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SIO_RTEMS_SHOW_STATS:
+ enet_stats (sc);
+ break;
+
+ /*
+ * FIXME: All sorts of multicast commands need to be added here!
+ */
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+
+#ifdef MPC860T
+static int
+fec_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+ struct m8xx_enet_struct *sc = ifp->if_softc;
+ int error = 0;
+
+ switch (command) {
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ ether_ioctl (ifp, command, data);
+ break;
+
+ case SIOCSIFFLAGS:
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+ case IFF_RUNNING:
+ fec_stop (sc);
+ break;
+
+ case IFF_UP:
+ fec_init (sc);
+ break;
+
+ case IFF_UP | IFF_RUNNING:
+ fec_stop (sc);
+ fec_init (sc);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SIO_RTEMS_SHOW_STATS:
+ enet_stats (sc);
+ break;
+
+ /*
+ * FIXME: All sorts of multicast commands need to be added here!
+ */
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+#endif
+
+
+/*
+ * Attach an SCC driver to the system
+ */
+int
+rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+ struct m8xx_enet_struct *sc;
+ struct ifnet *ifp;
+ int mtu;
+ int unitNumber;
+ char *unitName;
+
+ /*
+ * Parse driver name
+ */
+ if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
+ return 0;
+
+ /*
+ * Is driver free?
+ */
+ if ((unitNumber <= 0) || (unitNumber > NIFACES)) {
+ printf ("Bad SCC unit number.\n");
+ return 0;
+ }
+ sc = &enet_driver[unitNumber - 1];
+ ifp = &sc->arpcom.ac_if;
+ if (ifp->if_softc != NULL) {
+ printf ("Driver already in use.\n");
+ return 0;
+ }
+
+ /*
+ * Process options
+ */
+ if (config->hardware_address) {
+ memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+ }
+ else {
+ /* FIXME to read the enaddr from NVRAM */
+ }
+
+ if (config->mtu)
+ mtu = config->mtu;
+ else
+ mtu = ETHERMTU;
+ if (config->rbuf_count)
+ sc->rxBdCount = config->rbuf_count;
+ else
+ sc->rxBdCount = RX_BUF_COUNT;
+ if (config->xbuf_count)
+ sc->txBdCount = config->xbuf_count;
+ else
+ sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+ sc->acceptBroadcast = !config->ignore_broadcast;
+
+ /*
+ * Set up network interface values
+ */
+ ifp->if_softc = sc;
+ ifp->if_unit = unitNumber;
+ ifp->if_name = unitName;
+ ifp->if_mtu = mtu;
+ ifp->if_init = scc_init;
+ ifp->if_ioctl = scc_ioctl;
+ ifp->if_start = m8xx_enet_start;
+ ifp->if_output = ether_output;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+ /*
+ * Attach the interface
+ */
+ if_attach (ifp);
+ ether_ifattach (ifp);
+ return 1;
+};
+
+
+#ifdef MPC860T
+int
+rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+ struct m8xx_enet_struct *sc;
+ struct ifnet *ifp;
+ int mtu;
+ int unitNumber;
+ char *unitName;
+
+ /*
+ * Parse driver name
+ */
+ if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
+ return 0;
+
+ /*
+ * Is driver free?
+ */
+ if ((unitNumber <= 0) || (unitNumber > NIFACES)) {
+ printf ("Bad SCC unit number.\n");
+ return 0;
+ }
+ sc = &enet_driver[unitNumber - 1];
+ ifp = &sc->arpcom.ac_if;
+ if (ifp->if_softc != NULL) {
+ printf ("Driver already in use.\n");
+ return 0;
+ }
+
+ /*
+ * Process options
+ */
+ if (config->hardware_address) {
+ memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+ }
+ else {
+ /* FIXME to read the enaddr from NVRAM */
+ }
+ if (config->mtu)
+ mtu = config->mtu;
+ else
+ mtu = ETHERMTU;
+ if (config->rbuf_count)
+ sc->rxBdCount = config->rbuf_count;
+ else
+ sc->rxBdCount = RX_BUF_COUNT;
+ if (config->xbuf_count)
+ sc->txBdCount = config->xbuf_count;
+ else
+ sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+ sc->acceptBroadcast = !config->ignore_broadcast;
+
+ /*
+ * Set up network interface values
+ */
+ ifp->if_softc = sc;
+ ifp->if_unit = unitNumber;
+ ifp->if_name = unitName;
+ ifp->if_mtu = mtu;
+ ifp->if_init = fec_init;
+ ifp->if_ioctl = fec_ioctl;
+ ifp->if_start = m8xx_enet_start;
+ ifp->if_output = ether_output;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+ /*
+ * Attach the interface
+ */
+ if_attach (ifp);
+ ether_ifattach (ifp);
+ return 1;
+};
+#endif
+
+
+int
+rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+
+#ifdef MPC860T
+ if ((m8xx.fec.mii_data & 0xffff) == 0x2000) {
+/* rtems_scc1_driver_attach(config);*/
+ return rtems_fec_driver_attach(config);
+ }
+ else {
+#endif
+ return rtems_scc1_driver_attach(config);
+#ifdef MPC860T
+ }
+#endif
+}
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am
new file mode 100644
index 0000000000..3b2eb17f8d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/Makefile.am
@@ -0,0 +1,42 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+VPATH = @srcdir@:@srcdir@/../../../shared
+
+PGM = $(ARCH)/startup.rel
+
+C_FILES = bspclean.c bsplibc.c bsppost.c bspstart.c bootcard.c imbx8xx.c main.c \
+ mmutlbtab.c sbrk.c setvec.c gnatinstallhandler.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+S_FILES = start.s
+S_O_FILES = $(S_FILES:%.s=$(ARCH)/%.o)
+
+OBJS = $(C_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(OBJS)
+ $(make-rel)
+
+$(PROJECT_RELEASE)/lib/linkcmds: linkcmds
+ $(INSTALL_DATA) $< $@
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/linkcmds
+
+all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = bspstart.c imbx8xx.c linkcmds mmutlbtab.c setvec.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c
new file mode 100644
index 0000000000..2180df9b44
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c
@@ -0,0 +1,193 @@
+/* bspstart.c
+ *
+ * This set of routines 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.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications for MBX860:
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application (in ROM) and our copy of it with
+ * some changes. Configuration is defined in <confdefs.h>. Make sure that
+ * our configuration tables are uninitialized so that they get allocated in
+ * the .bss section (RAM).
+ */
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines.
+ * Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
+ * rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * bsp_pretasking_hook
+ *
+ * Called when RTEMS initialization is complete but before interrupts and
+ * tasking are enabled. Used to setup libc and install any BSP extensions.
+ *
+ * Must not use libc (to do io) from here, since drivers are not yet
+ * initialized.
+ *
+ * Installed in the rtems_cpu_table defined in
+ * rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
+ * rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_pretasking_hook(void)
+{
+ /*
+ * These are assigned addresses in the linkcmds file for the BSP. This
+ * approach is better than having these defined as manifest constants and
+ * compiled into the kernel, but it is still not ideal when dealing with
+ * multiprocessor configuration in which each board as a different memory
+ * map. A better place for defining these symbols might be the makefiles.
+ * Consideration should also be given to developing an approach in which
+ * the kernel and the application can be linked and burned into ROM
+ * independently of each other.
+ */
+ extern unsigned char _HeapStart;
+ extern unsigned char _HeapEnd;
+
+ bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif /* STACK_CHECKER_ON */
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+/*
+ * bsp_start()
+ *
+ * Board-specific initialization code. Called from the generic boot_card()
+ * function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
+ * does some of the board independent initialization. It is called from the
+ * MBX8xx entry point _start() defined in
+ * rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
+ *
+ * _start() has set up a stack, has zeroed the .bss section, has turned off
+ * interrupts, and placed the processor in the supervisor mode. boot_card()
+ * has left the processor in that state when bsp_start() was called.
+ *
+ * RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
+ * ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
+ * ADDRESSES. Software-controlled address translation would be required
+ * otherwise.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_start(void)
+{
+ extern void *_WorkspaceBase;
+
+ mmu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+ #ifdef INSTRUCTION_CACHE_ENABLE
+ rtems_enable_inst_cache();
+ #endif
+
+ #ifdef DATA_CACHE_ENABLE
+ rtems_enable_data_cache();
+ #endif
+
+ /*
+ * 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.
+ *
+ * In this case, the memory is not malloc'ed. It is just
+ * "pulled from the air".
+ */
+ BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
+
+ /*
+ * initialize the CPU table for this BSP
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ if( Cpu_table.interrupt_stack_size < 4 * 1024 )
+ Cpu_table.interrupt_stack_size = 4 * 1024;
+
+ Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
+ Cpu_table.serial_per_sec = 10000000;
+ Cpu_table.serial_external_clock = 1;
+ Cpu_table.serial_xon_xoff = 0;
+ Cpu_table.serial_cts_rts = 1;
+ Cpu_table.serial_rate = 9600;
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ Cpu_table.clock_speed = 50000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#else
+ Cpu_table.clock_speed = 40000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#endif
+
+ /*
+ * Call this in case we use TERMIOS for console I/O
+ */
+ m8xx_uart_reserve_resources( &BSP_Configuration );
+
+ m8xx.scc2.sccm=0;
+ m8xx.scc2p.rbase=0;
+ m8xx.scc2p.tbase=0;
+ m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache
new file mode 100644
index 0000000000..055e84ad27
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c.nocache
@@ -0,0 +1,202 @@
+/* bspstart.c
+ *
+ * This set of routines 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.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications for MBX860:
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application (in ROM) and our copy of it with
+ * some changes. Configuration is defined in <confdefs.h>. Make sure that
+ * our configuration tables are uninitialized so that they get allocated in
+ * the .bss section (RAM).
+ */
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines.
+ * Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
+ * rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * bsp_pretasking_hook
+ *
+ * Called when RTEMS initialization is complete but before interrupts and
+ * tasking are enabled. Used to setup libc and install any BSP extensions.
+ *
+ * Must not use libc (to do io) from here, since drivers are not yet
+ * initialized.
+ *
+ * Installed in the rtems_cpu_table defined in
+ * rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
+ * rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_pretasking_hook(void)
+{
+ /*
+ * These are assigned addresses in the linkcmds file for the BSP. This
+ * approach is better than having these defined as manifest constants and
+ * compiled into the kernel, but it is still not ideal when dealing with
+ * multiprocessor configuration in which each board as a different memory
+ * map. A better place for defining these symbols might be the makefiles.
+ * Consideration should also be given to developing an approach in which
+ * the kernel and the application can be linked and burned into ROM
+ * independently of each other.
+ */
+ extern unsigned char _HeapStart;
+ extern unsigned char _HeapEnd;
+
+ bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif /* STACK_CHECKER_ON */
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+/*
+ * bsp_start()
+ *
+ * Board-specific initialization code. Called from the generic boot_card()
+ * function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
+ * does some of the board independent initialization. It is called from the
+ * MBX8xx entry point _start() defined in
+ * rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
+ *
+ * _start() has set up a stack, has zeroed the .bss section, has turned off
+ * interrupts, and placed the processor in the supervisor mode. boot_card()
+ * has left the processor in that state when bsp_start() was called.
+ *
+ * RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
+ * ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
+ * ADDRESSES. Software-controlled address translation would be required
+ * otherwise.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_start(void)
+{
+ extern void *_WorkspaceBase;
+ unsigned32 r1;
+
+ mmu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+ #ifdef INSTRUCTION_CACHE_ENABLE
+ r1 = M8xx_CACHE_CMD_ENABLE;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ #endif
+
+ /*
+ * Warning: EPPCBug 1.1 chokes to death if the data cache is turned on.
+ * Set DATA_CACHE_ENABLE to zero in mbx8xx.cfg if EPPCBUG is used.
+ */
+ #ifdef DATA_CACHE_ENABLE
+ r1 = M8xx_CACHE_CMD_ENABLE;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ #endif
+
+ /*
+ * 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.
+ *
+ * In this case, the memory is not malloc'ed. It is just
+ * "pulled from the air".
+ */
+ BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
+
+ /*
+ * initialize the CPU table for this BSP
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ if( Cpu_table.interrupt_stack_size < 4 * 1024 )
+ Cpu_table.interrupt_stack_size = 4 * 1024;
+
+ Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
+ Cpu_table.serial_per_sec = 10000000;
+ Cpu_table.serial_external_clock = 1;
+ Cpu_table.serial_xon_xoff = 0;
+ Cpu_table.serial_cts_rts = 1;
+ Cpu_table.serial_rate = 9600;
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ Cpu_table.clock_speed = 50000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#else
+ Cpu_table.clock_speed = 40000000;
+ Cpu_table.timer_average_overhead = 3;
+ Cpu_table.timer_least_valid = 3;
+#endif
+
+ /*
+ * Call this in case we use TERMIOS for console I/O
+ */
+ m8xx_uart_reserve_resources( &BSP_Configuration );
+
+ m8xx.scc2.sccm=0;
+ m8xx.scc2p.rbase=0;
+ m8xx.scc2p.tbase=0;
+ m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c
new file mode 100644
index 0000000000..423f933079
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c
@@ -0,0 +1,535 @@
+/*
+ * imbx8xx.c
+ *
+ * MBX860/MBX821 initialization routines.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+
+/*
+ * EPPCBug rev 1.1 is stupid. It clears the interrupt mask register
+ * in the SIU when it takes control, but does not restore it before
+ * returning control to the program. We thus keep a copy of the
+ * register, and restore it from gdb using the hook facilities.
+ *
+ * We arrange for simask_copy to be initialized to zero so that
+ * it resides in the .data section. This avoids having gdb set
+ * the mask to crud before we get to initialize explicitly. Of
+ * course, the code will not be safely restartable, but then again,
+ * a lot of the library code isn't either, so there!
+ */
+unsigned32 simask_copy = 0;
+
+/*
+ * The memory controller's UPMA Ram array values.
+ * The values in table 2-6 and 2-7 in the "MBX Series Embedded
+ * Controller Programmer's Reference Guide", part number MBXA/PG2,
+ * differ from the ones in the older MBX Programmer's Guide, part
+ * number MBXA/PG1. We are assuming that the values in MBXA/PG1
+ * are for the older MBX boards whose part number does not have
+ * the "B" suffix, but we have discovered that the values from
+ * MBXA/PG2 work better, even for the older boards.
+ *
+ * THESE VALUES HAVE ONLY BEEN VERIFIED FOR THE MBX821-001 and
+ * MBX860-002. USE WITH CARE!
+ *
+ * NOTE: The MBXA/PG2 manual lists the clock speed of the MBX821_001B
+ * as being 50 MHz, while the MBXA/IH2.1 manual lists it as 40 MHz.
+ * We think the MBX821_001B is an entry level board and thus is 50 MHz,
+ */
+static unsigned32 upmaTable[64] = {
+
+#if ( defined(mbx860_001b) || \
+ defined(mbx821_001b) || \
+ defined(mbx821_001) )
+
+ /* 50 MHz MBX */
+ /*
+ * Note: For the mbx821_001, the following values (from the
+ * MBXA/PG2 manual) work better than, but are different
+ * from those published in the original MBXA/PG1 manual and
+ * initialized by EPPCBug 1.1. In particular, the original
+ * burst-write values do not work! Also, the following values
+ * facilitate higher performance.
+ */
+ /* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+ 0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x00AF0C04,
+ 0x07AF0C08, 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08,
+ 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08, 0x0CAF0C04,
+ 0x10AF0C04, 0xF0AFC000, 0xF3BF4805, 0xFFFFC005,
+
+ /* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+ 0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Refresh 60ns. (offset 0x30 in UPM RAM) */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Exception. (offset 0x3c in UPM RAM) */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
+
+#elif ( defined(mbx860_002b) || \
+ defined(mbx860_003b) || \
+ defined(mbx860_004b) || \
+ defined(mbx860_005b) || \
+ defined(mbx860_006b) || \
+ defined(mbx821_002b) || \
+ defined(mbx821_003b) || \
+ defined(mbx821_004b) || \
+ defined(mbx821_005b) || \
+ defined(mbx821_006b) || \
+ defined(mbx860_001) || \
+ defined(mbx860_002) || \
+ defined(mbx860_003) || \
+ defined(mbx860_004) || \
+ defined(mbx860_005) || \
+ defined(mbx821_002) || \
+ defined(mbx821_003) || \
+ defined(mbx821_004) || \
+ defined(mbx821_005) )
+
+ /* 40 MHz MBX */
+ /*
+ * Note: For the older MBX models (i.e. without the "b"
+ * suffix, e.g. mbx860_001), the following values (from the
+ * MBXA/PG2 manual) work better than, but are different
+ * from those published in the original MBXA/PG1 manual and
+ * initialized by EPPCBug 1.1. In particular, the following
+ * burst-read and burst-write values facilitate higher
+ * performance.
+ */
+ /* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+ 0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x33FF4804,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
+ 0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Refresh 60ns. (offset 0x30 in UPM RAM) */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* Exception. (offset 0x3c in UPM RAM) */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
+#else
+#error "MBX board model not specified."
+#endif
+};
+
+/*
+ * Initialize MBX8xx
+ */
+void _InitMBX8xx (void)
+{
+ register unsigned32 r1, i;
+ extern unsigned32 simask_copy;
+
+ /*
+ * Get the SIU interrupt mask.
+ */
+ simask_copy = m8xx.simask;
+
+ /*
+ * Initialize the Debug Enable Register (DER) to an appropriate
+ * value for EPPCBug debugging.
+ * (This value should also work for BDM debugging.)
+ */
+ r1 = 0x70C67C07; /* All except EXTIE, ALIE, DECIE */
+ _mtspr( M8xx_DER, r1 );
+
+ /*
+ * Initialize the Instruction Support Control Register (ICTRL) to a
+ * an appropriate value for normal operation. A different value,
+ * such as 0x0, may be more appropriate for debugging.
+ */
+ r1 = 0x00000007;
+ _mtspr( M8xx_ICTRL, r1 );
+
+ /*
+ * Disable and invalidate the instruction and data caches.
+ */
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+
+ /*
+ * Initialize the Internal Memory Map Register (IMMR)
+ *
+ * Use the value in MBXA/PG2, which is also the value that EPPC-Bug
+ * programmed into our boards. The alternative is the value in
+ * MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+ * of the firmware.
+ *
+ * THIS VALUE IS ALSO DECLARED IN THE linkcmds FILE and mmutlbtab.c!
+ */
+ r1 = 0xFA200000;
+ _mtspr( M8xx_IMMR, r1 );
+
+ /*
+ * Initialize the SIU Module Configuration Register (SIUMCR)
+ * m8xx.siumcr = 0x00602900, the default MBX and firmware value.
+ */
+ m8xx.siumcr = M8xx_SIUMCR_EARP0 | M8xx_SIUMCR_DBGC3 | M8xx_SIUMCR_DBPC0 |
+ M8xx_SIUMCR_DPC | M8xx_SIUMCR_MLRC2 | M8xx_SIUMCR_SEME;
+
+ /*
+ * Initialize the System Protection Control Register (SYPCR).
+ * The SYPCR can only be written once after Reset.
+ * - Enable bus monitor
+ * - Disable software watchdog timer
+ * m8xx.sypcr = 0xFFFFFF88, the default MBX and firmware value.
+ */
+ m8xx.sypcr = M8xx_SYPCR_SWTC(0xFFFF) | M8xx_SYPCR_BMT(0xFF) |
+ M8xx_SYPCR_BME | M8xx_SYPCR_SWF;
+
+ /* Initialize the SIU Interrupt Edge Level Mask Register (SIEL) */
+ m8xx.siel = 0xAAAA0000; /* Default MBX and firmware value. */
+
+ /* Initialize the Transfer Error Status Register (TESR) */
+ m8xx.tesr = 0xFFFFFFFF; /* Default firmware value. */
+
+ /* Initialize the SDMA Configuration Register (SDCR) */
+ m8xx.sdcr = 0x00000001; /* Default firmware value. */
+
+ /*
+ * Initialize the Timebase Status and Control Register (TBSCR)
+ * m8xx.tbscr = 0x00C3, default MBX and firmware value.
+ */
+ m8xx.tbscrk = M8xx_UNLOCK_KEY; /* unlock TBSCR */
+ m8xx.tbscr = M8xx_TBSCR_REFA | M8xx_TBSCR_REFB |
+ M8xx_TBSCR_TBF | M8xx_TBSCR_TBE;
+
+ /* Initialize the Real-Time Clock Status and Control Register (RTCSC) */
+ m8xx.rtcsk = M8xx_UNLOCK_KEY; /* unlock RTCSC */
+ m8xx.rtcsc = 0x00C3; /* Default MBX and firmware value. */
+
+ /* Unlock other Real-Time Clock registers */
+ m8xx.rtck = M8xx_UNLOCK_KEY; /* unlock RTC */
+ m8xx.rtseck = M8xx_UNLOCK_KEY; /* unlock RTSEC */
+ m8xx.rtcalk = M8xx_UNLOCK_KEY; /* unlock RTCAL */
+
+ /* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
+ m8xx.piscrk = M8xx_UNLOCK_KEY; /* unlock PISCR */
+ m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
+
+ /* Initialize the System Clock and Reset Control Register (SCCR)
+ * Set the clock sources and division factors:
+ * Timebase Source is GCLK2 / 16
+ * Real-Time Clock Select is EXTCLK (4.192MHz)
+ * Real-Time Clock Divide is /4
+ */
+ m8xx.sccrk = M8xx_UNLOCK_KEY; /* unlock SCCR */
+ m8xx.sccr = 0x02800000; /* for MBX860/MBX821 */
+
+ /* Initialize the PLL, Low-Power, and Reset Control Register (PLPRCR) */
+ /* - set the clock speed and set normal power mode */
+ m8xx.plprck = M8xx_UNLOCK_KEY; /* unlock PLPRCR */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.plprcr = 0x5F500000;
+#else
+ m8xx.plprcr = 0x4C400000;
+#endif
+ /* Unlock the timebase and decrementer registers. */
+ m8xx.tbk = M8xx_UNLOCK_KEY;
+
+ /*
+ * Initialize decrementer register to a large value to
+ * guarantee that a decrementer interrupt will not be
+ * generated before the kernel is fully initialized.
+ */
+ r1 = 0x7FFFFFFF;
+ _mtspr( M8xx_DEC, r1 );
+
+ /* Initialize the timebase register (TB is 64 bits) */
+ r1 = 0x00000000;
+ _mtspr( M8xx_TBU_WR, r1 );
+ _mtspr( M8xx_TBL_WR, r1 );
+
+ /*
+ * Memory Controller Initialization
+ */
+
+ /*
+ * User Programmable Machine A (UPMA) Initialization
+ *
+ * If this initialization code is running from DRAM, it is very
+ * dangerous to change the value of any UPMA Ram array word from
+ * what the firmware (EPPCBug) initialized it to. Thus we don't
+ * initialize UPMA if EPPCBUG_VECTORS is defined; we assume EPPCBug
+ * has done the appropriate initialization.
+ *
+ * An exception to our rule, is that, for the older MBX boards
+ * (those without the "B" suffix, e.g. MBX821-001 and MBX860-002),
+ * we do re-initialize the burst-read and burst-write values with
+ * values that are more efficient. Also, in the MBX821 case,
+ * the burst-write original values set by EPPCBug do not work!
+ * This change can be done safely because the caches have not yet
+ * been activated.
+ *
+ * The RAM array of UPMA is initialized by writing to each of
+ * its 64 32-bit RAM locations.
+ * Note: UPM register initialization should occur before
+ * initialization of the corresponding BRx and ORx registers.
+ */
+#if ( !defined(EPPCBUG_VECTORS) )
+ for( i = 0; i < 64; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+#elif ( defined(mbx860_001) || \
+ defined(mbx860_002) || \
+ defined(mbx860_003) || \
+ defined(mbx860_004) || \
+ defined(mbx860_005) || \
+ defined(mbx821_001) || \
+ defined(mbx821_002) || \
+ defined(mbx821_003) || \
+ defined(mbx821_004) || \
+ defined(mbx821_005) )
+ /* Replace the burst-read and burst-write values with better ones. */
+ /* burst-read values */
+ for( i = 8; i < 24; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+ /* burst-write values */
+ for( i = 32; i < 48; ++i ) {
+ m8xx.mdr = upmaTable[i];
+ m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
+ }
+#endif
+
+#if ( !defined(EPPCBUG_VECTORS) )
+ /*
+ * Initialize the memory periodic timer.
+ * Memory Periodic Timer Prescaler Register (MPTPR: 16-bit register)
+ * m8xx.mptpr = 0x0200;
+ */
+ m8xx.mptpr = M8xx_MPTPR_PTP(0x2);
+
+ /*
+ * Initialize the Machine A Mode Register (MAMR)
+ *
+ * ASSUMES THAT DIMMs ARE NOT INSTALLED!
+ *
+ * Without DIMMs:
+ * m8xx.mamr = 0x13821000 (40 MHz) or 0x18821000 (50 MHz).
+ *
+ * With DIMMs:
+ * m8xx.mamr = 0x06821000 (40 MHz) or 0x08821000 (50 MHz).
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.mamr = M8xx_MEMC_MMR_PTP(0x18) | M8xx_MEMC_MMR_PTE |
+ M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
+#else
+ m8xx.mamr = M8xx_MEMC_MMR_PTP(0x13) | M8xx_MEMC_MMR_PTE |
+ M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
+#endif
+#endif /* ! defined(EPPCBUG_VECTORS) */
+
+ /*
+ * Initialize the Base and Option Registers (BR0-BR7 and OR0-OR7)
+ * Note: For all chip selects, ORx should be programmed before BRx,
+ * except when programming the boot chip select (CS0) after hardware
+ * reset, in which case, BR0 should be programmed before OR0.
+ *
+ * MPC860/MPX821 Memory Map Summary:
+ * S-ADDR E-ADDR CS PS PE WP MS BI V DESCRIPTION
+ * FE000000 FE7FFFFF 0 32 N N GPCM Y Y Soldered FLASH Memory
+ * 00000000 00zFFFFF 1 32 N N UPMA N Y Local DRAM Memory
+ * 00X00000 0XXXXXXX 2 0 N N UPMA N N DIMM Memory - Bank #0
+ * 00X00000 0XXXXXXX 3 0 N N UPMA N N DIMM Memory - Bank #1
+ * FA000000 FA1FFFFF 4 8 N N GPCM Y Y NVRAM & BCSR
+ * 80000000 DFFFFFFF 5 32 N N GPCM Y Y PCI/ISA I/O & Memory
+ * FA210000 FA21FFFF 6 32 N N GPCM Y Y QSpan Registers
+ * FC000000 FC7FFFFF 7 8 N N GPCM Y Y Socketed FLASH Memory
+ *
+ * z = 3 for 4MB installed on the motherboard, z = F for 16M
+ *
+ * NOTE: The devices selected by CS0 and CS7 can be selected with jumper J4.
+ * This table assumes that the 32-bit soldered flash device is the boot ROM.
+ */
+
+ /*
+ * CS0 : Soldered (32-bit) Flash Memory at 0xFE000000
+ *
+ * CHANGE THIS CODE IF YOU CHANGE JUMPER J4 FROM ITS FACTORY DEFAULT SETTING!
+ * (or better yet, don't reprogram BR0 and OR0; just program BR7 and OR7 to
+ * access whatever flash device is not selected during hard reset.)
+ *
+ * MBXA/PG2 appears to lie in note 14 for table 2-4. The manual states that
+ * "EPPCBUG configures the reset flash device at the lower address, and the
+ * nonreset flash device at the higher address." If we take reset flash device
+ * to mean the boot flash memory, then the statement must mean that BR0 must
+ * point to the device at the lower address, i.e. 0xFC000000, while BR7 must
+ * point to the device at the highest address, i.e. 0xFE000000.
+ *
+ * THIS IS NOT THE CASE!
+ *
+ * The boot flash is always configured to start at 0xFE000000, and the other
+ * one to start at 0xFC000000. Changing jumper J4 only changes the width of
+ * the memory ports into these two region.
+ *
+ * BR0 = 0xFE000001
+ * Base addr [0-16] 0b11111110000000000 = 0xFE000000
+ * Address type [17-19] 0b000
+ * Port size [20-21] 0b00 = 32 bits
+ * Parity enable [22] 0b0 = disabled
+ * Write protect [23] 0b0 = r/w
+ * Machine select [24-25] 0b00 = GPCM
+ * Reserved [26-30] 0b00000
+ * Valid Bit [31] 0b1 = this bank is valid
+ * OR0 = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
+ * Address mask [0-16] 0b11111111100000000 = 0xFF800000
+ * Addr type mask [17-19] 0b000 = no address-type protection
+ * CS negation time [20] 0b1
+ * ACS [21-22] 0b00 = CS output at same time as address lines
+ * Burst inhibit [23] 0b1 = bank does not support burst accesses
+ * Cycle length [24-27] 0b0011/0b0100 = 3/4 clock cycle wait states
+ * SETA [28] 0b0 = TA generated internally
+ * Timing relaxed [29] 0b0 = not relaxed
+ * Extended hold time [30] 0b0 = not extended
+ * Reserved [31] 0b0
+ *
+ * m8xx.memc[0]._or = 0xFF800930 (40 MHz)
+ * m8xx.memc[0]._or = 0xFF800940 (50 MHz)
+ * m8xx.memc[0]._br = 0xFE000001
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
+#else
+ m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#endif
+ m8xx.memc[0]._br = M8xx_BR_BA(0xFE000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS1 : Local DRAM Memory at 0x00000000
+ * m8xx.memc[1]._or = 0xFFC00400;
+ * m8xx.memc[1]._br = 0x00000081;
+ */
+ m8xx.memc[1]._or = M8xx_MEMC_OR_4M | M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[1]._br = M8xx_BR_BA(0x00000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA | M8xx_MEMC_BR_V;
+
+ /*
+ * CS2 : DIMM Memory - Bank #0, not present
+ * m8xx.memc[2]._or = 0x00000400;
+ * m8xx.memc[2]._br = 0x00000080;
+ */
+ m8xx.memc[2]._or = M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[2]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
+
+ /*
+ * CS3 : DIMM Memory - Bank #1, not present
+ * m8xx.memc[3]._or = 0x00000400;
+ * m8xx.memc[3]._br = 0x00000080;
+ */
+ m8xx.memc[3]._or = M8xx_MEMC_OR_ATM(0) |
+ M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
+ m8xx.memc[3]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
+
+ /*
+ * CS4 : Battery-Backed SRAM at 0xFA000000
+ * m8xx.memc[4]._or = 0xFFE00920@ 40 MHz, 0xFFE00930 @ 50 MHz
+ * m8xx.memc[4]._br = 0xFA000401;
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#else
+ m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(2);
+#endif
+ m8xx.memc[4]._br = M8xx_BR_BA(0xFA000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS5 : PCI I/O and Memory at 0x80000000
+ * m8xx.memc[5]._or = 0xA0000108;
+ * m8xx.memc[5]._br = 0x80000001;
+ */
+ m8xx.memc[5]._or = 0xA0000000 | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
+ M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
+ m8xx.memc[5]._br = M8xx_BR_BA(0x80000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS6 : QSPAN Registers at 0xFA210000
+ * m8xx.memc[6]._or = 0xFFFF0108;
+ * m8xx.memc[6]._br = 0xFA210001;
+ */
+ m8xx.memc[6]._or = M8xx_MEMC_OR_64K | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
+ M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
+ m8xx.memc[6]._br = M8xx_BR_BA(0xFA210000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+
+ /*
+ * CS7 : Socketed (8-bit) Flash at 0xFC000000
+ * m8xx.memc[7]._or = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
+ * m8xx.memc[7]._br = 0xFC000401;
+ */
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+ m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
+#else
+ m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
+ M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
+#endif
+ m8xx.memc[7]._br = M8xx_BR_BA(0xFC000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
+ M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
+}
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds b/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds
new file mode 100644
index 0000000000..565e7f175b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/linkcmds
@@ -0,0 +1,259 @@
+/*
+ * This file contains directives for the GNU linker that are specific
+ * to the MBX860-2 board.
+ *
+ * $Id$
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(start)
+
+/*
+ * Declare some sizes.
+ * XXX: The assignment of ". += XyzSize;" fails in older gld's if the
+ * number used there is not constant. If this happens to you, edit
+ * the lines marked XXX below to use a constant value.
+ */
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x100000; /* 1M Heap */
+StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
+
+MEMORY
+ {
+ ram : org = 0x0, l = 4M
+ nvram : org = 0xfa000000, l = 32K
+ dpram : org = 0xfa200000, l = 16K
+ flash : org = 0xfc000000, l = 2M
+ immr : org = 0xfa200000, l = 16K
+ }
+
+
+SECTIONS
+{
+ /*
+ * If the vectors are specified statically rather than created at run time,
+ * accumulate them starting at VMA 0x0.
+ */
+ .vectors :
+ {
+ *(.vectors)
+ } >ram
+
+ /*
+ * The stack will live in this area - between the vectors and
+ * the text section.
+ */
+
+ .text 0x10000:
+ {
+ /* Read-only sections, merged into text segment: */
+
+ text.start = .;
+
+ /* Entry point is the .entry section */
+ *(.entry)
+ *(.entry2)
+
+ /* Actual code */
+ *(.text)
+ *(.text.*)
+
+ /* C++ constructors/destructors */
+ *(.gnu.linkonce.t*)
+
+ /* Initialization and finalization code.
+ *
+ * Various files can provide initialization and finalization functions.
+ * The bodies of these functions are in .init and .fini sections. We
+ * accumulate the bodies here, and prepend function prologues from
+ * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
+ * first; ecrtn.o must be linked last. Because these are wildcards, it
+ * doesn't matter if the user does not actually link against ecrti.o and
+ * ecrtn.o; the linker won't look for a file to match a wildcard. The
+ * wildcard also means that it doesn't matter which directory ecrti.o
+ * and ecrtn.o are in.
+ */
+ PROVIDE (_init = .);
+ *ecrti.o(.init)
+ *(.init)
+ *ecrtn.o(.init)
+
+ PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ *(.fini)
+ *ecrtn.o(.init)
+
+ /*
+ * C++ constructors and destructors for static objects.
+ * PowerPC EABI does not use crtstuff yet, so we build "old-style"
+ * constructor and destructor lists that begin with the list lenght
+ * end terminate with a NULL entry.
+ */
+
+ PROVIDE (__CTOR_LIST__ = .);
+ /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.ctors)
+ *(.ctors)
+ *crtend.o(.ctors)
+ LONG(0)
+ PROVIDE (__CTOR_END__ = .);
+
+ PROVIDE (__DTOR_LIST__ = .);
+ /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.dtors)
+ *(.dtors)
+ *crtend.o(.dtors)
+ LONG(0)
+ PROVIDE (__DTOR_END__ = .);
+
+ /* Exception frame info */
+ *(.eh_frame)
+
+ /* Miscellaneous read-only data */
+ _rodata_start = . ;
+ *(.gnu.linkonce.r*)
+ *(.lit)
+ *(.shdata)
+ *(.rodata)
+ *(.rodata1)
+ *(.descriptors)
+ *(rom_ver)
+ _erodata = .;
+
+
+ /* Various possible names for the end of the .text section */
+ etext = ALIGN(0x10);
+ _etext = .;
+ _endtext = .;
+ text.end = .;
+ PROVIDE (etext = .);
+ PROVIDE (__etext = .);
+ } > ram
+
+ /* R/W Data */
+ .data :
+ {
+ data_start = .;
+
+ *(.data)
+ *(.data.*)
+ *(.data1)
+
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata)
+ *(.gnu.linkonce.d*)
+ PROVIDE (__SDATA_END__ = .);
+
+ PROVIDE (__EXCEPT_START__ = .);
+ *(.gcc_except_table)
+ PROVIDE (__EXCEPT_END__ = .);
+
+ PROVIDE(__GOT_START__ = .);
+ *(.got.plt)
+ *(.got)
+ PROVIDE(__GOT_END__ = .);
+
+ *(.got1)
+
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ *(.got2)
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ *(.fixup)
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ /* We want the small data sections together, so single-instruction offsets
+ * can access them all.
+ */
+ PROVIDE (__SDATA2_START__ = .);
+ *(.sdata2)
+ PROVIDE (__SDATA2_END__ = .);
+ } > ram
+
+
+ .bss :
+ {
+ PROVIDE (__SBSS_START__ = .);
+
+ PROVIDE (__SBSS2_START__ = .);
+ *(.sbss2)
+ PROVIDE (__SBSS2_END__ = .);
+
+ bss.start = .;
+ *(.bss)
+ *(.sbss)
+ *(COMMON)
+ . = ALIGN(4);
+ bss.end = .;
+
+ PROVIDE (__SBSS_END__ = .);
+
+ } > ram
+
+ bss.size = bss.end - bss.start;
+ text.size = text.end - text.start;
+ PROVIDE(_end = bss.end);
+
+ _HeapStart = .;
+ __HeapStart = .;
+ . += HeapSize; /* XXX -- Old gld can't handle this */
+ /* . += 0x80000; */ /* HeapSize for old gld */
+ _HeapEnd = .;
+ __HeapEnd = .;
+ clear_end = .;
+
+ _WorkspaceBase = .;
+ __WorkspaceBase = .;
+
+ dpram :
+ {
+ m8xx = .;
+ _m8xx = .;
+ . += (16 * 1024);
+ } >immr
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c
new file mode 100644
index 0000000000..45c22d8951
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/mmutlbtab.c
@@ -0,0 +1,132 @@
+/*
+ * mmutlbtab.c
+ *
+ * This file defines the MMU_TLB_table for the MBX8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+
+/*
+ * This MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of the MBX8xx board.
+ *
+ * We initialize the entries in both the instruction and data TLBs
+ * with the same values - a few bits relevant to the data TLB are unused
+ * in the instruction TLB.
+ *
+ * An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
+ * Real Page Number (RPN) value are supplied in the table for each TLB entry.
+ *
+ * The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
+ * not have more than 32 lines in it!
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+MMU_TLB_table_t MMU_TLB_table[] = {
+ /*
+ * DRAM: CS1, Start address 0x00000000, 4M,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, not cache-inhibited.
+ * Last 512K block is cache-inhibited, but not guarded for use by EPPCBug.
+ * EPN TWC RPN
+ */
+ { 0x00000200, 0x05, 0x000009FD }, /* DRAM - PS=512K */
+ { 0x00080200, 0x05, 0x000809FD }, /* DRAM - PS=512K */
+ { 0x00100200, 0x05, 0x001009FD }, /* DRAM - PS=512K */
+ { 0x00180200, 0x05, 0x001809FD }, /* DRAM - PS=512K */
+ { 0x00200200, 0x05, 0x002009FD }, /* DRAM - PS=512K */
+ { 0x00280200, 0x05, 0x002809FD }, /* DRAM - PS=512K */
+ { 0x00300200, 0x05, 0x003009FD }, /* DRAM - PS=512K */
+ { 0x00380200, 0x05, 0x003809FF }, /* DRAM - PS=512K, cache-inhibited */
+ /*
+ *
+ * NVRAM: CS4, Start address 0xFA000000, 32K,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ *
+ * EPN TWC RPN
+ */
+ { 0xFA000200, 0x01, 0xFA0009FF }, /* NVRAM - PS=16K */
+ { 0xFA004200, 0x01, 0xFA0049FF }, /* NVRAM - PS=16K */
+ /*
+ *
+ * Board Control/Status Register #1/#2: CS4, Start address 0xFA100000, (4 x 8 bits?)
+ * ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFA100200, 0x11, 0xFA1009F7 }, /* BCSR - PS=4K */
+ /*
+ *
+ * (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
+ * ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ *
+ * Note: We use the value in MBXA/PG2, which is also the value that
+ * EPPC-Bug programmed into our boards. The alternative is the value
+ * in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+ * of the firmware.
+ * EPN TWC RPN
+ */
+ { 0xFA200200, 0x11, 0xFA2009FF }, /* IMMR - PS=16K */
+ /*
+ *
+ * Flash: CS0, Start address 0xFE000000, 4M, (BootROM-EPPCBug)
+ * ASID=0x0, APG=0x0, not guarded memory,
+ * R/O,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFE000200, 0x05, 0xFE000CFD }, /* Flash - PS=512K */
+ { 0xFE080200, 0x05, 0xFE080CFD }, /* Flash - PS=512K */
+ { 0xFE100200, 0x05, 0xFE100CFD }, /* Flash - PS=512K */
+ { 0xFE180200, 0x05, 0xFE180CFD }, /* Flash - PS=512K */
+ { 0xFE200200, 0x05, 0xFE200CFD }, /* Flash - PS=512K */
+ { 0xFE280200, 0x05, 0xFE280CFD }, /* Flash - PS=512K */
+ { 0xFE300200, 0x05, 0xFE300CFD }, /* Flash - PS=512K */
+ { 0xFE380200, 0x05, 0xFE380CFD }, /* Flash - PS=512K */
+ /*
+ * BootROM: CS7, Start address 0xFC000000, 4M?, (socketed FLASH)
+ * ASID=0x0, APG=0x0, not guarded memory,
+ * R/O,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFC000200, 0x05, 0xFC000CFD }, /* BootROM - PS=512K */
+ /*
+ *
+ * PCI/ISA I/O Space: CS5, Start address 0x80000000, 512M?
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0x80000200, 0x1D, 0x800009FF }, /* PCI I/O - PS=8M */
+ /*
+ *
+ * PCI/ISA Memory Space: CS5, Start address 0xC0000000, 512M?
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xC0000200, 0x1D, 0xC00009FF }, /* PCI Memory - PS=8M */
+ /*
+ *
+ * PCI Bridge/QSPAN Registers: CS6, Start address 0xFA210000, 4K
+ * ASID=0x0, APG=0x0, guarded memory,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0xFA210200, 0x11, 0xFA2109F7 } /* QSPAN - PS=4K */
+};
+
+/*
+ * MMU_N_TLB_Table_Entries is defined here because the size of the
+ * MMU_TLB_table is only known in this file.
+ */
+int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c b/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c
new file mode 100644
index 0000000000..b32dc8aaec
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/setvec.c
@@ -0,0 +1,44 @@
+/* set_vector
+ *
+ * This routine installs an interrupt vector on the target Board/CPU.
+ * This routine is allowed to be as board dependent as necessary.
+ *
+ * INPUT:
+ * handler - interrupt handler entry point
+ * vector - vector number
+ * type - 0 indicates raw hardware connect
+ * 1 indicates RTEMS interrupt connect
+ *
+ * RETURNS:
+ * address of previous interrupt handler
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+rtems_isr_entry set_vector( /* returns old vector */
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector, /* vector number */
+ int type /* RTEMS or RAW intr */
+)
+{
+ rtems_isr_entry previous_isr;
+
+ if (type) {
+ rtems_interrupt_catch(handler, vector, (rtems_isr_entry *) &previous_isr );
+ } else {
+ /* XXX: install non-RTEMS ISR as "raw" interupt */
+ }
+ return previous_isr;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S b/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
new file mode 100644
index 0000000000..c487a58a33
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
@@ -0,0 +1,383 @@
+/* start.S
+ *
+ * This file contains the entry veneer for RTEMS programs
+ * on the MBX8xx board.
+ * It jumps to the BSP which is responsible for performing
+ * all remaining initialization.
+ *
+ * This file is based on several others:
+ *
+ * (1) start360.s from the gen68360 BSP by
+ * W. Eric Norum (eric@skatter.usask.ca)
+ * with the following copyright and license:
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * 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.
+ *
+ * (2) start.s for the eth_comm port by
+ * Jay Monkman (jmonkman@fracsa.com),
+ * which itself is based on the
+ *
+ * (3) dlentry.s for the Papyrus BSP, written by:
+ * Andrew Bray <andy@i-cubed.co.uk>
+ * with the following copyright and license:
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * (4) start860.S for the MBX821/MBX860, written by:
+ * Darlene A. Stewart <darlene.stewart@iit.nrc.ca>
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications (for MBX8xx) of respective RTEMS files:
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include "asm.h"
+
+/*
+ * The initial stack is set to run BELOW the code base address.
+ * (between the vectors and text sections)
+ *
+ * All the entry veneer has to do is to clear the BSS.
+ */
+
+/*
+ * GDB likes to have debugging information for the entry veneer.
+ * Play compiler and provide some DWARF information.
+ *
+ * CHANGE TO SUIT YOUR SETUP!
+ */
+
+ .section .entry,"ax",@progbits
+.L_text_b:
+.L_LC1:
+ .previous
+
+.section .debug_sfnames
+.L_sfnames_b:
+ .byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
+ .byte 0
+.L_F0:
+ .byte "start.S"
+ .byte 0
+ .previous
+
+.section .line
+.L_line_b:
+ .4byte .L_line_e-.L_line_b
+ .4byte .L_text_b
+.L_LE1:
+.L_line_last:
+ .4byte 0x0
+ .2byte 0xffff
+ .4byte .L_text_e-.L_text_b
+.L_line_e:
+ .previous
+
+.section .debug_srcinfo
+.L_srcinfo_b:
+ .4byte .L_line_b
+ .4byte .L_sfnames_b
+ .4byte .L_text_b
+ .4byte .L_text_e
+ .4byte 0xffffffff
+ .4byte .L_LE1-.L_line_b
+ .4byte .L_F0-.L_sfnames_b
+ .4byte .L_line_last-.L_line_b
+ .4byte 0xffffffff
+ .previous
+
+.section .debug_pubnames
+ .4byte .L_debug_b
+ .4byte .L_P0
+ .byte "start"
+ .byte 0
+ .4byte 0x0
+ .byte 0
+ .previous
+
+.section .debug_aranges
+ .4byte .L_debug_b
+ .4byte .L_text_b
+ .4byte .L_text_e-.L_text_b
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0x0
+ .4byte 0x0
+ .previous
+
+.section .debug
+.L_debug_b:
+.L_D1:
+ .4byte .L_D1_e-.L_D1
+ .2byte 0x11 /* TAG_compile_unit */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D2
+ .2byte 0x38 /* AT_name */
+ .byte "start.S"
+ .byte 0
+ .2byte 0x258 /* AT_producer */
+ .byte "GAS 2.5.2"
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x106 /* AT_stmt_list */
+ .4byte .L_line_b
+ .2byte 0x1b8 /* AT_comp_dir */
+ .byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
+ .byte 0
+ .2byte 0x8006 /* AT_sf_names */
+ .4byte .L_sfnames_b
+ .2byte 0x8016 /* AT_src_info */
+ .4byte .L_srcinfo_b
+.L_D1_e:
+.L_P0:
+.L_D3:
+ .4byte .L_D3_e-.L_D3
+ .2byte 0x6 /* TAG_global_subroutine */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D4
+ .2byte 0x38 /* AT_name */
+ .byte "start"
+ .byte 0
+ .2byte 0x278 /* AT_prototyped */
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x8041 /* AT_body_begin */
+ .4byte .L_text_b
+ .2byte 0x8051 /* AT_body_end */
+ .4byte .L_text_e
+.L_D3_e:
+
+.L_D4:
+ .4byte .L_D4_e-.L_D4
+ .align 2
+.L_D4_e:
+.L_D2:
+ .previous
+
+/*
+ * Tell C's eabi-ctor's that we have an atexit function,
+ * and that it is to register __do_global_dtors.
+ */
+ EXTERN_PROC(atexit)
+ PUBLIC_VAR(__atexit)
+ .section ".sdata","aw"
+ .align 2
+SYM(__atexit):
+ EXT_PROC_REF(atexit)@fixup
+ .previous
+
+ .section ".fixup","aw"
+ .align 2
+ EXT_SYM_REF(__atexit)
+ .previous
+
+/* That should do it */
+
+/*
+ * Put the entry point in its own section. That way, we can guarantee
+ * to put it first in the .text section in the linker script.
+ */
+ .section .entry
+
+ PUBLIC_VAR (start)
+SYM(start):
+ bl .startup /* or bl .spin */
+base_addr:
+
+/*
+ * Parameters from linker
+ */
+toc_pointer:
+ .long __GOT_START__
+bss_length:
+ .long bss.size
+bss_addr:
+ .long bss.start
+
+PUBLIC_VAR (text_addr)
+text_addr:
+ .long text.start
+
+PUBLIC_VAR (text_length)
+text_length:
+ .long text.size
+
+/*
+ * Spin, if necessary, to acquire control from debugger (CodeWarrior).
+ */
+spin:
+ .long 0x0001
+.spin:
+ lis r3, spin@ha
+ lwz r3, spin@l(r3)
+ cmpwi r3, 0x1
+ beq .spin
+
+/*
+ * Initialization code
+ */
+.startup:
+ /* Get the start address. */
+ mflr r1
+
+ /* Initialize essential registers. */
+ bl initregs
+ nop
+
+ /*
+ * C_setup.
+ */
+
+ /* set toc */
+ lwz r2, toc_pointer-base_addr(r1)
+
+ /* Set up stack pointer = beginning of text section - 56 */
+ addi r1, r1, -56-4
+
+ /* Initialize the memory mapped MPC821 registers (done in C). */
+ EXTERN_PROC (_InitMBX8xx)
+ bl PROC (_InitMBX8xx)
+ nop
+
+ /* Clear the bss section. */
+ bl bssclr
+ nop
+
+ /* clear argc and argv */
+ xor r3, r3, r3
+ xor r4, r4, r4
+
+ EXTERN_PROC (boot_card)
+ bl PROC (boot_card) /* call the first C routine */
+ nop
+
+ /* we should never return from boot_card, but in case we do ... */
+ /* The next instructions are dependent on your runtime environment */
+
+ /* Return to EPPCBug */
+ lis r10, 0x0400 /* Data cache disable */
+ mtspr 568, r10
+ isync
+
+ mtspr 560, r10 /* Instruction cache disable */
+ isync
+
+stop_here:
+ li r10, 0x0F00 /* .RETURN */
+ sc
+
+ b stop_here
+ nop
+
+/*
+ * bssclr - zero out bss
+ */
+bssclr:
+ lis r3, base_addr@ha
+ addi r3, r3, base_addr@l
+ lwz r4, bss_addr-base_addr(r3) /* Start of bss */
+ lwz r5, bss_length-base_addr(r3) /* Length of bss */
+
+ rlwinm. r5,r5,30,0x3FFFFFFF /* form length/4 */
+ beqlr /* no bss - return */
+ mtctr r5 /* set ctr reg */
+
+ li r5,0x0000 /* r5 = 0 */
+clear_bss:
+ stw r5,0(r4) /* store r6 */
+ addi r4,r4,0x4 /* update r4 */
+ bdnz clear_bss /* dec counter and loop */
+
+ blr /* return */
+
+/*
+ * initregs
+ * Initialize the MSR and basic core PowerPC registers
+ *
+ * Register usage:
+ * r0 - scratch
+ */
+initregs:
+ /*
+ * Disable address translation. We should already be running in real space,
+ * so this should be a no-op, i.e. no need to switch instruction stream
+ * addresses from virtual space to real space. Other bits set the processor
+ * for big-endian mode, exceptions vectored to 0x000n_nnnn (vectors are
+ * already in low memory!), no execution tracing, machine check exceptions
+ * enabled, floating-point not available (MPC8xx has none), supervisor
+ * priviledge level, external interrupts disabled, power management
+ * disabled (normal operation mode).
+ */
+ li r0, 0x1000 /* MSR_ME */
+ mtmsr r0 /* Context-synchronizing */
+ isync
+
+ /*
+ * Clear the exception handling registers.
+ * Note SPRG3 is reserved for use by EPPCBug on the MBX8xx.
+ */
+ li r0, 0x0000
+ mtdar r0
+ mtspr sprg0, r0
+ mtspr sprg1, r0
+ mtspr sprg2, r0
+ mtspr srr0, r0
+ mtspr srr1, r0
+
+ mr r6, r0
+ mr r7, r0
+ mr r8, r0
+ mr r9, r0
+ mr r10, r0
+ mr r11, r0
+ mr r12, r0
+ mr r13, r0
+ mr r14, r0
+ mr r15, r0
+ mr r16, r0
+ mr r17, r0
+ mr r18, r0
+ mr r19, r0
+ mr r20, r0
+ mr r21, r0
+ mr r22, r0
+ mr r23, r0
+ mr r24, r0
+ mr r25, r0
+ mr r26, r0
+ mr r27, r0
+ mr r28, r0
+ mr r29, r0
+ mr r30, r0
+ mr r31, r0
+
+ blr /* return */
+
+.L_text_e:
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx821 b/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx821
new file mode 100644
index 0000000000..53e6b133a9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx821
@@ -0,0 +1,191 @@
+#
+# Timing Test Suite Results for the MBX821-001
+#
+# $Id$
+#
+
+Board: MBX821
+CPU: MPC821
+Clock Speed: 50 MHz
+Memory Configuration: 4Mb EDO, 60ns DRAM
+Wait States:
+
+Times Reported in: clock ticks
+Timer Source: Timebase register (TMBCLK = (cpu clock speed / 16) = 3.125MHz)
+
+Column A: Data & instruction caches disabled (2000-05-04)
+Column B: Data & instruction caches enabled (UPM/A: new burst r/w values) (2000-05-04)
+
+# DESCRIPTION A B
+== ================================================================= ==== ====
+ 1 rtems_semaphore_create 181 79
+ rtems_semaphore_delete 196 55
+ rtems_semaphore_obtain: available 128 12
+ rtems_semaphore_obtain: not available -- NO_WAIT 128 12
+ rtems_semaphore_release: no waiting tasks 162 16
+
+ 2 rtems_semaphore_obtain: not available -- caller blocks 405 113
+
+ 3 rtems_semaphore_release: task readied -- preempts caller 317 72
+
+ 4 rtems_task_restart: blocked task -- preempts caller 549 156
+ rtems_task_restart: ready task -- preempts caller 539 150
+ rtems_semaphore_release: task readied -- returns to caller 201 25
+ rtems_task_create 585 153
+ rtems_task_start 257 67
+ rtems_task_restart: suspended task -- returns to caller 309 83
+ rtems_task_delete: suspended task 555 118
+ rtems_task_restart: ready task -- returns to caller 317 85
+ rtems_task_restart: blocked task -- returns to caller 374 113
+ rtems_task_delete: blocked task 571 130
+
+ 5 rtems_task_suspend: calling task 314 63
+ rtems_task_resume: task readied -- preempts caller 263 49
+
+ 6 rtems_task_restart: calling task 385 53
+ rtems_task_suspend: returns to caller 132 18
+ rtems_task_resume: task readied -- returns to caller 145 20
+ rtems_task_delete: ready task 574 135
+
+ 7 rtems_task_restart: suspended task -- preempts caller 505 111
+
+ 8 rtems_task_set_priority: obtain current priority 111 11
+ rtems_task_set_priority: returns to caller 207 20
+ rtems_task_mode: obtain current mode 56 6
+ rtems_task_mode: no reschedule 70 8
+ rtems_task_mode: reschedule -- returns to caller 75 32
+ rtems_task_mode: reschedule -- preempts caller 292 97
+ rtems_task_set_note 112 11
+ rtems_task_get_note 113 11
+ rtems_clock_set 250 25
+ rtems_clock_get 6 1
+
+ 9 rtems_message_queue_create 751 320
+ rtems_message_queue_send: no waiting tasks 241 33
+ rtems_message_queue_urgent: no waiting tasks 238 39
+ rtems_message_queue_receive: available 229 29
+ rtems_message_queue_flush: no messages flushed 104 12
+ rtems_message_queue_flush: messages flushed 127 12
+ rtems_message_queue_delete 242 83
+
+10 rtems_message_queue_receive: not available -- NO_WAIT 147 16
+ rtems_message_queue_receive: not available -- caller blocks 416 94
+
+11 rtems_message_queue_send: task readied -- preempts caller 377 82
+
+12 rtems_message_queue_send: task readied -- returns to caller 262 50
+
+13 rtems_message_queue_urgent: task readied -- preempts caller 377 85
+
+14 rtems_message_queue_urgent: task readied -- returns to caller 262 43
+
+15 rtems_event_receive: obtain current events 10 1
+ rtems_event_receive: not available -- NO_WAIT 102 9
+ rtems_event_receive: not available -- caller blocks 346 76
+ rtems_event_send: no task readied 104 10
+ rtems_event_receive: available 105 24
+ rtems_event_send: task readied -- returns to caller 181 26
+
+16 rtems_event_send: task readied -- preempts caller 308 78
+
+17 rtems_task_set_priority: preempts caller 408 76
+
+18 rtems_task_delete: calling task 749 174
+
+19 rtems_signal_catch 75 9
+ rtems_signal_send: returns to caller 120 35
+ rtems_signal_send: signal to self 198 74
+ exit ASR overhead: returns to calling task 158 63
+ exit ASR overhead: returns to preempting task 249 65
+
+20 rtems_partition_create 247 102
+ rtems_region_create 196 78
+ rtems_partition_get_buffer: available 117 26
+ rtems_partition_get_buffer: not available 110 10
+ rtems_partition_return_buffer 127 30
+ rtems_partition_delete 145 31
+ rtems_region_get_segment: available 156 19
+ rtems_region_get_segment: not available -- NO_WAIT 143 36
+ rtems_region_return_segment: no waiting tasks 167 15
+ rtems_region_get_segment: not available -- caller blocks 429 167
+ rtems_region_return_segment: task readied -- preempts caller 418 142
+ rtems_region_return_segment: task readied -- returns to caller 298 71
+ rtems_region_delete 146 25
+ rtems_io_initialize 13 2
+ rtems_io_open 9 1
+ rtems_io_close 9 1
+ rtems_io_read 9 1
+ rtems_io_write 9 1
+ rtems_io_control 9 1
+
+21 rtems_task_ident 1143 139
+ rtems_message_queue_ident 1115 141
+ rtems_semaphore_ident 1285 158
+ rtems_partition_ident 1115 132
+ rtems_region_ident 1137 144
+ rtems_port_ident 1115 133
+ rtems_timer_ident 1117 140
+ rtems_rate_monotonic_ident 1116 136
+
+22 rtems_message_queue_broadcast: task readied -- returns to caller 281 84
+ rtems_message_queue_broadcast: no waiting tasks 177 17
+ rtems_message_queue_broadcast: task readied -- preempts caller 398 114
+
+23 rtems_timer_create 127 15
+ rtems_timer_fire_after: inactive 191 23
+ rtems_timer_fire_after: active 204 24
+ rtems_timer_cancel: active 118 15
+ rtems_timer_cancel: inactive 104 13
+ rtems_timer_reset: inactive 176 21
+ rtems_timer_reset: active 189 22
+ rtems_timer_fire_when: inactive 237 28
+ rtems_timer_fire_when: active 237 28
+ rtems_timer_delete: active 167 25
+ rtems_timer_delete: inactive 153 23
+ rtems_task_wake_when 408 83
+
+24 rtems_task_wake_after: yield -- returns to caller 85 8
+ rtems_task_wake_after: yields -- preempts caller 287 56
+
+25 rtems_clock_tick 59 25
+
+26 _ISR_Disable 3 1
+ _ISR_Flash 3 0
+ _ISR_Enable 1 0
+ _Thread_Disable_dispatch 4 0
+ _Thread_Enable_dispatch 59 6
+ _Thread_Set_state 59 16
+ _Thread_Disptach (NO FP) 242 52
+ context switch: no floating point contexts 183 44
+ context switch: self 62 2
+ context switch: to another task 64 3
+ context switch: restore 1st FP task 189 40
+ fp context switch: save idle, restore idle 186 39
+ fp context switch: save idle, restore initialized 67 4
+ fp context switch: save initialized, restore initialized 67 5
+ _Thread_Resume 51 24
+ _Thread_Unblock 47 12
+ _Thread_Ready 54 9
+ _Thread_Get 33 3
+ _Semaphore_Get 26 2
+ _Thread_Get: invalid id 5 0
+
+27 interrupt entry overhead: returns to interrupted task 0 0
+ interrupt exit overhead: returns to interrupted task 1 1
+ interrupt entry overhead: returns to nested interrupt 0 0
+ interrupt exit overhead: returns to nested interrupt 0 0
+ interrupt entry overhead: returns to preempting task
+ interrupt exit overhead: returns to preempting task
+
+28 rtems_port_create 145 55
+ rtems_port_external_to_internal 101 9
+ rtems_port_internal_to_external 101 9
+ rtems_port_delete 144 40
+
+29 rtems_rate_monotonic_create 135 57
+ rtems_rate_monotonic_period: initiate period -- returns to caller 176 77
+ rtems_rate_monotonic_period: obtain status 110 35
+ rtems_rate_monotonic_cancel 131 50
+ rtems_rate_monotonic_delete: inactive 160 61
+ rtems_rate_monotonic_delete: active 178 41
+ rtems_rate_monotonic_period: conclude periods -- caller blocks 284 67
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx860 b/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx860
new file mode 100644
index 0000000000..d99737f9a1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/times-mbx860
@@ -0,0 +1,191 @@
+#
+# Timing Test Suite Results for the MBX860-002
+#
+# $Id$
+#
+
+Board: MBX860
+CPU: MPC860
+Clock Speed: 40 MHz
+Memory Configuration: 4Mb EDO, 60ns DRAM
+Wait States:
+
+Times Reported in: clock ticks
+Timer Source: Timebase register (TMBCLK = (cpu clock speed / 16) = 2.5Mhz)
+
+Column A: Data & instruction caches disabled (2000-05-03)
+Column B: Data & instruction caches enabled (UPM/A: new burst r/w values) (2000-05-04)
+
+# DESCRIPTION A B
+== ================================================================= ==== ====
+ 1 rtems_semaphore_create 159 67
+ rtems_semaphore_delete 173 52
+ rtems_semaphore_obtain: available 113 26
+ rtems_semaphore_obtain: not available -- NO_WAIT 113 28
+ rtems_semaphore_release: no waiting tasks 144 22
+
+ 2 rtems_semaphore_obtain: not available -- caller blocks 346 121
+
+ 3 rtems_semaphore_release: task readied -- preempts caller 268 89
+
+ 4 rtems_task_restart: blocked task -- preempts caller 475 130
+ rtems_task_restart: ready task -- preempts caller 465 132
+ rtems_semaphore_release: task readied -- returns to caller 179 48
+ rtems_task_create 521 154
+ rtems_task_start 228 57
+ rtems_task_restart: suspended task -- returns to caller 275 74
+ rtems_task_delete: suspended task 494 139
+ rtems_task_restart: ready task -- returns to caller 283 78
+ rtems_task_restart: blocked task -- returns to caller 333 98
+ rtems_task_delete: blocked task 507 144
+
+ 5 rtems_task_suspend: calling task 266 88
+ rtems_task_resume: task readied -- preempts caller 220 61
+
+ 6 rtems_task_restart: calling task 334 75
+ rtems_task_suspend: returns to caller 117 24
+ rtems_task_resume: task readied -- returns to caller 129 29
+ rtems_task_delete: ready task 510 138
+
+ 7 rtems_task_restart: suspended task -- preempts caller 436 135
+
+ 8 rtems_task_set_priority: obtain current priority 98 11
+ rtems_task_set_priority: returns to caller 183 32
+ rtems_task_mode: obtain current mode 51 8
+ rtems_task_mode: no reschedule 62 9
+ rtems_task_mode: reschedule -- returns to caller 66 25
+ rtems_task_mode: reschedule -- preempts caller 246 69
+ rtems_task_set_note 99 11
+ rtems_task_get_note 100 23
+ rtems_clock_set 222 35
+ rtems_clock_get 6 1
+
+ 9 rtems_message_queue_create 667 262
+ rtems_message_queue_send: no waiting tasks 215 58
+ rtems_message_queue_urgent: no waiting tasks 212 53
+ rtems_message_queue_receive: available 204 43
+ rtems_message_queue_flush: no messages flushed 93 17
+ rtems_message_queue_flush: messages flushed 113 22
+ rtems_message_queue_delete 214 76
+
+10 rtems_message_queue_receive: not available -- NO_WAIT 131 20
+ rtems_message_queue_receive: not available -- caller blocks 357 118
+
+11 rtems_message_queue_send: task readied -- preempts caller 322 109
+
+12 rtems_message_queue_send: task readied -- returns to caller 234 67
+
+13 rtems_message_queue_urgent: task readied -- preempts caller 322 94
+
+14 rtems_message_queue_urgent: task readied -- returns to caller 234 62
+
+15 rtems_event_receive: obtain current events 8 1
+ rtems_event_receive: not available -- NO_WAIT 90 9
+ rtems_event_receive: not available -- caller blocks 294 88
+ rtems_event_send: no task readied 91 10
+ rtems_event_receive: available 93 22
+ rtems_event_send: task readied -- returns to caller 161 41
+
+16 rtems_event_send: task readied -- preempts caller 260 84
+
+17 rtems_task_set_priority: preempts caller 349 108
+
+18 rtems_task_delete: calling task 652 203
+
+19 rtems_signal_catch 66 9
+ rtems_signal_send: returns to caller 107 41
+ rtems_signal_send: signal to self 176 62
+ exit ASR overhead: returns to calling task 140 56
+ exit ASR overhead: returns to preempting task 207 54
+
+20 rtems_partition_create 220 78
+ rtems_region_create 175 71
+ rtems_partition_get_buffer: available 103 21
+ rtems_partition_get_buffer: not available 97 10
+ rtems_partition_return_buffer 113 24
+ rtems_partition_delete 128 26
+ rtems_region_get_segment: available 137 27
+ rtems_region_get_segment: not available -- NO_WAIT 126 36
+ rtems_region_return_segment: no waiting tasks 148 31
+ rtems_region_get_segment: not available -- caller blocks 366 119
+ rtems_region_return_segment: task readied -- preempts caller 359 114
+ rtems_region_return_segment: task readied -- returns to caller 265 72
+ rtems_region_delete 129 33
+ rtems_io_initialize 12 2
+ rtems_io_open 9 1
+ rtems_io_close 9 1
+ rtems_io_read 9 1
+ rtems_io_write 9 1
+ rtems_io_control 9 1
+
+21 rtems_task_ident 1019 137
+ rtems_message_queue_ident 993 139
+ rtems_semaphore_ident 1144 162
+ rtems_partition_ident 993 132
+ rtems_region_ident 1012 143
+ rtems_port_ident 993 132
+ rtems_timer_ident 994 138
+ rtems_rate_monotonic_ident 993 135
+
+22 rtems_message_queue_broadcast: task readied -- returns to caller 249 80
+ rtems_message_queue_broadcast: no waiting tasks 157 27
+ rtems_message_queue_broadcast: task readied -- preempts caller 340 94
+
+23 rtems_timer_create 114 15
+ rtems_timer_fire_after: inactive 170 36
+ rtems_timer_fire_after: active 182 36
+ rtems_timer_cancel: active 104 14
+ rtems_timer_cancel: inactive 92 12
+ rtems_timer_reset: inactive 156 29
+ rtems_timer_reset: active 168 31
+ rtems_timer_fire_when: inactive 210 43
+ rtems_timer_fire_when: active 210 42
+ rtems_timer_delete: active 148 24
+ rtems_timer_delete: inactive 136 20
+ rtems_task_wake_when 350 99
+
+24 rtems_task_wake_after: yield -- returns to caller 76 10
+ rtems_task_wake_after: yields -- preempts caller 242 63
+
+25 rtems_clock_tick 51 19
+
+26 _ISR_Disable 3 0
+ _ISR_Flash 2 0
+ _ISR_Enable 0 0
+ _Thread_Disable_dispatch 3 0
+ _Thread_Enable_dispatch 52 8
+ _Thread_Set_state 51 15
+ _Thread_Disptach (NO FP) 201 53
+ context switch: no floating point contexts 148 44
+ context switch: self 41 4
+ context switch: to another task 44 5
+ context switch: restore 1st FP task 154 41
+ fp context switch: save idle, restore idle 152 42
+ fp context switch: save idle, restore initialized 46 5
+ fp context switch: save initialized, restore initialized 47 4
+ _Thread_Resume 45 19
+ _Thread_Unblock 42 10
+ _Thread_Ready 47 8
+ _Thread_Get 29 3
+ _Semaphore_Get 23 2
+ _Thread_Get: invalid id 5 0
+
+27 interrupt entry overhead: returns to interrupted task 0 0
+ interrupt exit overhead: returns to interrupted task 0 0
+ interrupt entry overhead: returns to nested interrupt 0 0
+ interrupt exit overhead: returns to nested interrupt 0 0
+ interrupt entry overhead: returns to preempting task
+ interrupt exit overhead: returns to preempting task
+
+28 rtems_port_create 128 48
+ rtems_port_external_to_internal 90 9
+ rtems_port_internal_to_external 90 13
+ rtems_port_delete 128 30
+
+29 rtems_rate_monotonic_create 120 48
+ rtems_rate_monotonic_period: initiate period -- returns to caller 156 55
+ rtems_rate_monotonic_period: obtain status 98 27
+ rtems_rate_monotonic_cancel 115 39
+ rtems_rate_monotonic_delete: inactive 141 51
+ rtems_rate_monotonic_delete: active 158 46
+ rtems_rate_monotonic_period: conclude periods -- caller blocks 240 76
diff --git a/c/src/lib/libbsp/powerpc/mbx8xx/wrapup/Makefile.am b/c/src/lib/libbsp/powerpc/mbx8xx/wrapup/Makefile.am
new file mode 100644
index 0000000000..11de3f33b0
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mbx8xx/wrapup/Makefile.am
@@ -0,0 +1,40 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+# We only build the networking device driver if HAS_NETWORKING was defined
+if HAS_NETWORKING
+NETWORKING = network
+endif
+
+BSP_PIECES = startup console $(NETWORKING)
+# pieces to pick up out of libcpu/ppc
+# CPU_PIECES = mpc8xx/clock mpc8xx/console-generic mpc8xx/cpm \
+ mpc8xx/mmu mpc8xx/timer mpc8xx/vectors
+
+# bummer; have to use $foreach since % pattern subst rules only replace 1x
+OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.o))
+LIB = $(ARCH)/libbsp.a
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(LIB): $(OBJS)
+ $(make-library)
+
+$(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a: $(LIB)
+ $(INSTALL_DATA) $< $@
+
+TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a
+
+all-local: $(ARCH) $(OBJS) $(LIB) $(TMPINSTALL_FILES)
+
+.PRECIOUS: $(LIB)
+
+include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/support/old_exception_processing/Makefile.am b/c/src/lib/libbsp/powerpc/support/old_exception_processing/Makefile.am
index 9629808140..92f3fee811 100644
--- a/c/src/lib/libbsp/powerpc/support/old_exception_processing/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/support/old_exception_processing/Makefile.am
@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
-C_FILES = cpu.c ppccache.c
+C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =
diff --git a/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.c b/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.c
index 7d6824cb26..5a5fadfd97 100644
--- a/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.c
+++ b/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.c
@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
+int _CPU_spurious_count = 0;
+int _CPU_last_spurious = 0;
+
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
+ ++_CPU_spurious_count;
+ _CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
- case PPC_IRQ_CPM_RESERVED_0:
+ case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:
diff --git a/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.h b/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.h
index 2a502d0745..30dd6dc092 100644
--- a/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.h
+++ b/c/src/lib/libbsp/powerpc/support/old_exception_processing/cpu.h
@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
+#define _CPU_Data_Cache_Block_Invalidate( _address ) \
+ do { register void *__address = (_address); \
+ register unsigned32 _zero = 0; \
+ asm volatile ( "dcbi %0,%1" : \
+ "=r" (_zero), "=r" (__address) : \
+ "0" (_zero), "1" (__address) \
+ ); \
+ } while (0)
+
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
diff --git a/c/src/lib/libc/malloc.c b/c/src/lib/libc/malloc.c
index 08660d75cc..dc6824891a 100644
--- a/c/src/lib/libc/malloc.c
+++ b/c/src/lib/libc/malloc.c
@@ -418,5 +418,27 @@ void _free_r(
{
free( ptr );
}
+
+
+/*
+ * rtems_cache_aligned_malloc
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to allocate storage that spans an
+ * integral number of cache blocks.
+ */
+RTEMS_INLINE_ROUTINE void * rtems_cache_aligned_malloc (
+ size_t nbytes
+)
+{
+ /*
+ * Arrange to have the user storage start on the first cache
+ * block beyond the header.
+ */
+ return (void *) ((((unsigned long) malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ + _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
+}
+
#endif
diff --git a/c/src/lib/libc/termios.c b/c/src/lib/libc/termios.c
index 7883e94b63..5052502e76 100644
--- a/c/src/lib/libc/termios.c
+++ b/c/src/lib/libc/termios.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
+#include <sys/filio.h>
/*
* FreeBSD does not support a full POSIX termios so we have to help it out
@@ -243,7 +244,7 @@ rtems_termios_open (
/*
* Set default parameters
*/
- tty->termios.c_iflag = BRKINT | ICRNL | IMAXBEL;
+ tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
tty->termios.c_oflag = OPOST | ONLCR | XTABS;
tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
@@ -474,6 +475,11 @@ rtems_termios_ioctl (void *arg)
case RTEMS_IO_TCDRAIN:
drainOutput (tty);
break;
+
+ case FIONREAD:
+ /* Half guess that this is the right operation */
+ *(int *)args->buffer = tty->ccount - tty->cindex;
+ break;
}
rtems_semaphore_release (tty->osem);
args->ioctl_return = sc;
diff --git a/c/src/lib/libcpu/i386/cpu.h b/c/src/lib/libcpu/i386/cpu.h
index 27e5f1cb88..791173f15b 100644
--- a/c/src/lib/libcpu/i386/cpu.h
+++ b/c/src/lib/libcpu/i386/cpu.h
@@ -133,47 +133,6 @@ static inline unsigned short i386_get_gs()
}
/*
- * Added for pagination management
- */
-
-static inline unsigned int i386_get_cr0()
-{
- register unsigned int segment = 0;
-
- asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
-
- return segment;
-}
-
-static inline void i386_set_cr0(unsigned int segment)
-{
- asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
-}
-
-static inline unsigned int i386_get_cr2()
-{
- register unsigned int segment = 0;
-
- asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
-
- return segment;
-}
-
-static inline unsigned int i386_get_cr3()
-{
- register unsigned int segment = 0;
-
- asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
-
- return segment;
-}
-
-static inline void i386_set_cr3(unsigned int segment)
-{
- asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
-}
-
-/*
* IO Port Access Routines
*/
@@ -479,12 +438,6 @@ typedef struct {
page_table_entry pageTableEntry[MAX_ENTRY];
} page_table;
-static inline void flush_cache()
-{
- /* Would this be better as a macro? */
- asm ("wbinvd"); /* gcc did not like a volatile being on this */
-}
-
/* C declaration for paging management */
diff --git a/c/src/lib/libcpu/i386/page.c b/c/src/lib/libcpu/i386/page.c
index fc28b7687a..e5cceeed23 100644
--- a/c/src/lib/libcpu/i386/page.c
+++ b/c/src/lib/libcpu/i386/page.c
@@ -45,7 +45,7 @@ extern rtems_unsigned32 rtemsFreeMemStart;
void _CPU_disable_paging() {
cr0 regCr0;
- flush_cache();
+ rtems_flush_entire_data_cache();
regCr0.i = i386_get_cr0();
regCr0.cr0.paging = 0;
i386_set_cr0( regCr0.i );
@@ -60,7 +60,7 @@ void _CPU_enable_paging() {
regCr0.i = i386_get_cr0();
regCr0.cr0.paging = 1;
i386_set_cr0( regCr0.i );
- flush_cache();
+ rtems_flush_entire_data_cache();
}
@@ -154,32 +154,6 @@ int init_paging() {
}
/*
- * Disable the entire cache
- */
-void _CPU_disable_cache() {
- cr0 regCr0;
-
- regCr0.i = i386_get_cr0();
- regCr0.cr0.page_level_cache_disable = 1;
- regCr0.cr0.no_write_through = 1;
- i386_set_cr0( regCr0.i );
- flush_cache();
-}
-
-/*
- * Disable the entire cache
- */
-void _CPU_enable_cache() {
- cr0 regCr0;
-
- regCr0.i = i386_get_cr0();
- regCr0.cr0.page_level_cache_disable = 0;
- regCr0.cr0.no_write_through = 0;
- i386_set_cr0( regCr0.i );
- /*flush_cache();*/
-}
-
-/*
* Is cache enable
*/
int _CPU_is_cache_enabled() {
diff --git a/c/src/lib/libcpu/powerpc/Makefile.am b/c/src/lib/libcpu/powerpc/Makefile.am
index 9f82006795..26522c385c 100644
--- a/c/src/lib/libcpu/powerpc/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/Makefile.am
@@ -16,11 +16,8 @@ endif
if mpc6xx
CPU_SUBDIR = mpc6xx
endif
-if mpc821
-CPU_SUBDIR = mpc821
-endif
-if mpc860
-CPU_SUBDIR = mpc860
+if mpc8xx
+CPU_SUBDIR = mpc8xx
endif
if ppc403
CPU_SUBDIR = ppc403
diff --git a/c/src/lib/libcpu/powerpc/configure.in b/c/src/lib/libcpu/powerpc/configure.in
index dfeed3d186..db92d4bc8f 100644
--- a/c/src/lib/libcpu/powerpc/configure.in
+++ b/c/src/lib/libcpu/powerpc/configure.in
@@ -26,16 +26,20 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
-AM_CONDITIONAL(shared,
-test "$RTEMS_CPU_MODEL" = "mpc750" \
-|| test "$RTEMS_CPU_MODEL" = "mpc604" )
+AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "mpc750" \
+|| test "$RTEMS_CPU_MODEL" = "mpc604" \
+|| test "$RTEMS_CPU_MODEL" = "mpc6xx" \
+|| test "$RTEMS_CPU_MODEL" = "mpc821" \
+|| test "$RTEMS_CPU_MODEL" = "mpc860" \
+|| test "$RTEMS_CPU_MODEL" = "mpc8xx" )
AM_CONDITIONAL(mpc505, test "$RTEMS_CPU_MODEL" = "mpc505")
AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc604" \
|| test "$RTEMS_CPU_MODEL" = "mpc750" )
-AM_CONDITIONAL(mpc821, test "$RTEMS_CPU_MODEL" = "mpc821")
-AM_CONDITIONAL(mpc860, test "$RTEMS_CPU_MODEL" = "mpc860")
+AM_CONDITIONAL(mpc8xx, test "$RTEMS_CPU_MODEL" = "mpc8xx" \
+|| test "$RTEMS_CPU_MODEL" = "mpc821" \
+|| test "$RTEMS_CPU_MODEL" = "mpc860" )
AM_CONDITIONAL(ppc403, test "$RTEMS_CPU_MODEL" = "ppc403")
# Explicitly list all Makefiles here
@@ -44,18 +48,14 @@ Makefile
mpc505/Makefile
mpc505/timer/Makefile
mpc505/vectors/Makefile
-mpc821/Makefile
-mpc821/clock/Makefile
-mpc821/console-generic/Makefile
-mpc821/include/Makefile
-mpc821/timer/Makefile
-mpc821/vectors/Makefile
-mpc860/Makefile
-mpc860/clock/Makefile
-mpc860/console-generic/Makefile
-mpc860/include/Makefile
-mpc860/timer/Makefile
-mpc860/vectors/Makefile
+mpc8xx/Makefile
+mpc8xx/clock/Makefile
+mpc8xx/console-generic/Makefile
+mpc8xx/cpm/Makefile
+mpc8xx/include/Makefile
+mpc8xx/mmu/Makefile
+mpc8xx/timer/Makefile
+mpc8xx/vectors/Makefile
ppc403/Makefile
ppc403/clock/Makefile
ppc403/console/Makefile
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am
new file mode 100644
index 0000000000..3d9bd3de3b
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am
@@ -0,0 +1,10 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+SUBDIRS = include console-generic clock timer vectors cpm mmu
+
+include $(top_srcdir)/../../../../../automake/subdirs.am
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/README b/c/src/lib/libcpu/powerpc/mpc8xx/README
new file mode 100644
index 0000000000..99877ab6bf
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/README
@@ -0,0 +1,19 @@
+#
+# $Id$
+#
+
+Various non BSP dependant support routines.
+
+clock - Uses the MPC860/MPC821 PIT (Programmable interval timer) to
+ generate RTEMS clock ticks.
+
+console_generic - Uses the MPC860/MPC821 SCCs and SMCs to to serial I/O.
+
+include - console.h: function declarations for console related functions
+
+timer - Uses the MPC860/MPC821 timebase register for timing
+ tests. It only uses the lower 32 bits
+
+vectors - MPC860/MPC821 specific vector entry points.
+ Includes CPU dependant, application independant
+ handlers: alignment.
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/clock/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/clock/Makefile.am
new file mode 100644
index 0000000000..ff64e6e6e2
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/clock/Makefile.am
@@ -0,0 +1,30 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/clock.rel
+
+## C sources
+C_FILES = clock.c
+
+clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(clock_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c b/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c
new file mode 100644
index 0000000000..50de9d7772
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c
@@ -0,0 +1,188 @@
+/* clock.c
+ *
+ * This routine initializes the PIT on the MPC8xx.
+ * The tick frequency is specified by the bsp.
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h> /* for atexit() */
+#include <mpc8xx.h>
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+volatile rtems_unsigned32 Clock_driver_ticks;
+extern volatile m8xx_t m8xx;
+
+void Clock_exit( void );
+
+/*
+ * These are set by clock driver during its init
+ */
+
+rtems_device_major_number rtems_clock_major = ~0;
+rtems_device_minor_number rtems_clock_minor;
+
+/*
+ * ISR Handler
+ */
+rtems_isr Clock_isr(rtems_vector_number vector)
+{
+ m8xx.piscr |= M8xx_PISCR_PS;
+ Clock_driver_ticks++;
+ rtems_clock_tick();
+}
+
+void Install_clock(rtems_isr_entry clock_isr)
+{
+#ifdef EPPCBUG_SMC1
+ extern unsigned32 simask_copy;
+#endif /* EPPCBUG_SMC1 */
+
+ rtems_isr_entry previous_isr;
+ rtems_unsigned32 pit_value;
+
+ Clock_driver_ticks = 0;
+
+ pit_value = (BSP_Configuration.microseconds_per_tick *
+ Cpu_table.clicks_per_usec) - 1 ;
+
+ if (pit_value > 0xffff) { /* pit is only 16 bits long */
+ rtems_fatal_error_occurred(-1);
+ }
+ if (BSP_Configuration.ticks_per_timeslice) {
+
+ /*
+ * initialize the interval here
+ * First tick is set to right amount of time in the future
+ * Future ticks will be incremented over last value set
+ * in order to provide consistent clicks in the face of
+ * interrupt overhead
+ */
+
+ rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
+
+ m8xx.sccr &= ~(1<<24);
+ m8xx.pitc = pit_value;
+
+ /* set PIT irq level, enable PIT, PIT interrupts */
+ /* and clear int. status */
+ m8xx.piscr = M8xx_PISCR_PIRQ(0) |
+ M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
+
+#ifdef EPPCBUG_SMC1
+ simask_copy = m8xx.simask | M8xx_SIMASK_LVM0;
+#endif /* EPPCBUG_SMC1 */
+ m8xx.simask |= M8xx_SIMASK_LVM0;
+ }
+ atexit(Clock_exit);
+}
+
+void
+ReInstall_clock(rtems_isr_entry new_clock_isr)
+{
+ rtems_isr_entry previous_isr;
+ rtems_unsigned32 isrlevel = 0;
+
+ rtems_interrupt_disable(isrlevel);
+
+ rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
+
+ rtems_interrupt_enable(isrlevel);
+}
+
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ */
+void
+Clock_exit(void)
+{
+ if ( BSP_Configuration.ticks_per_timeslice ) {
+ /* disable PIT and PIT interrupts */
+ m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
+
+ (void) set_vector(0, PPC_IRQ_LVL0, 1);
+ }
+}
+
+rtems_device_driver Clock_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ Install_clock( Clock_isr );
+
+ /*
+ * make major/minor avail to others such as shared memory driver
+ */
+
+ rtems_clock_major = major;
+ rtems_clock_minor = minor;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver Clock_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_libio_ioctl_args_t *args = pargp;
+
+ if (args == 0)
+ goto done;
+
+ /*
+ * This is hokey, but until we get a defined interface
+ * to do this, it will just be this simple...
+ */
+
+ if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
+ Clock_isr(PPC_IRQ_LVL0);
+ }
+ else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
+ ReInstall_clock(args->buffer);
+ }
+
+ done:
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/Makefile.am
new file mode 100644
index 0000000000..4907257c76
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/Makefile.am
@@ -0,0 +1,30 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/console-generic.rel
+
+## C sources
+C_FILES = console-generic.c
+
+console_generic_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(console_generic_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c
new file mode 100644
index 0000000000..92c504d92e
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c
@@ -0,0 +1,1036 @@
+/*
+ * General Serial I/O functions.
+ *
+ * This file contains the functions for performing serial I/O.
+ * The actual system calls (console_*) should be in the BSP part
+ * of the source tree. That way different BSPs can use whichever
+ * SMCs and SCCs they want. Originally, all the stuff was in
+ * this file, and it caused problems with one BSP using SCC2
+ * as /dev/console, others using SMC1 for /dev/console, etc.
+ *
+ * On-chip resources used:
+ * resource minor note
+ * SMC1 0
+ * SMC2 1
+ * SCC1 2 N/A. Hardwired as ethernet port
+ * SCC2 3
+ * SCC3 4
+ * SCC4 5
+ * BRG1
+ * BRG2
+ * BRG3
+ * BRG4
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libbsp/m68k/gen360/console/console.c written by:
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found 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 <mpc8xx.h>
+#include <mpc8xx/console.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+
+extern rtems_cpu_table Cpu_table;
+
+#ifdef EPPCBUG_SMC1
+extern unsigned32 simask_copy;
+#endif /* EPPCBUG_SMC1 */
+
+/*
+ * Interrupt-driven input buffer
+ */
+#define RXBUFSIZE 16
+
+/*
+ * I/O buffers and pointers to buffer descriptors.
+ * Currently, single buffered input is done. This will work only
+ * if the Rx interrupts are serviced quickly.
+ *
+ * TODO: Add a least double buffering for safety.
+ */
+static volatile char rxBuf[NUM_PORTS][RXBUFSIZE];
+static volatile char txBuf[NUM_PORTS];
+
+/* SCC/SMC buffer descriptors */
+static volatile m8xxBufferDescriptor_t *RxBd[NUM_PORTS], *TxBd[NUM_PORTS];
+
+/* Used to track the usage of the baud rate generators */
+static unsigned long brg_spd[4];
+static char brg_used[4];
+
+/* Used to track termios private data for callbacks */
+struct rtems_termios_tty *ttyp[NUM_PORTS];
+
+/* Used to record previous ISR */
+static rtems_isr_entry old_handler[NUM_PORTS];
+
+/*
+ * Device-specific routines
+ */
+static int m8xx_get_brg_cd(int);
+static unsigned char m8xx_get_brg_clk(int);
+void m8xx_console_reserve_resources(rtems_configuration_table *);
+static int m8xx_smc_set_attributes(int, const struct termios*);
+static int m8xx_scc_set_attributes(int, const struct termios*);
+static rtems_isr m8xx_smc1_interrupt_handler(rtems_vector_number);
+static rtems_isr m8xx_smc2_interrupt_handler(rtems_vector_number);
+static rtems_isr m8xx_scc2_interrupt_handler(rtems_vector_number);
+#if defined(mpc860)
+static rtems_isr m8xx_scc3_interrupt_handler(rtems_vector_number);
+static rtems_isr m8xx_scc4_interrupt_handler(rtems_vector_number);
+#endif
+
+/*
+ * Compute baud-rate-generator configuration register value
+ */
+static int
+m8xx_get_brg_cd (int baud)
+{
+ int divisor;
+ int div16 = 0;
+
+ divisor = ((Cpu_table.clock_speed / 16) + (baud / 2)) / baud;
+ if (divisor > 4096) {
+ div16 = 1;
+ divisor = (divisor + 8) / 16;
+ }
+ return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK |
+ ((divisor - 1) << 1) | div16;
+}
+
+
+/*
+ * This function will fail if more that 4 baud rates have been selected
+ * at any time since the OS started. It needs to be fixed. FIXME
+ */
+static unsigned
+char m8xx_get_brg_clk(int baud)
+{
+ int i;
+
+ /* first try to find a BRG that is already at the right speed */
+ for ( i = 0; i < 4; i++ ) {
+ if ( brg_spd[i] == baud ) {
+ break;
+ }
+ }
+
+ if ( i == 4 ) { /* I guess we didn't find one */
+ for ( i = 0; i < 4; i++ ) {
+ if ( brg_used[i] == 0 ) {
+ break;
+ }
+ }
+ }
+ if (i != 4) {
+ brg_used[i]++;
+ brg_spd[i]=baud;
+ switch (i) {
+ case 0:
+ m8xx.brgc1 = M8xx_BRG_RST;
+ m8xx.brgc1 = m8xx_get_brg_cd(baud);
+ break;
+ case 1:
+ m8xx.brgc2 = M8xx_BRG_RST;
+ m8xx.brgc2 = m8xx_get_brg_cd(baud);
+ break;
+ case 2:
+ m8xx.brgc3 = M8xx_BRG_RST;
+ m8xx.brgc3 = m8xx_get_brg_cd(baud);
+ break;
+ case 3:
+ m8xx.brgc4 = M8xx_BRG_RST;
+ m8xx.brgc4 = m8xx_get_brg_cd(baud);
+ break;
+ }
+ return i;
+ }
+
+ else
+ return 0xff;
+}
+
+
+/*
+ * Hardware-dependent portion of tcsetattr().
+ */
+static int
+m8xx_smc_set_attributes (int minor, const struct termios *t)
+{
+ int baud, brg, csize, ssize, psize;
+ rtems_unsigned16 clen, cstopb, parenb, parodd, cread;
+
+ /* Baud rate */
+ switch (t->c_cflag & CBAUD) {
+ default: baud = -1; break;
+ case B50: baud = 50; break;
+ case B75: baud = 75; break;
+ case B110: baud = 110; break;
+ case B134: baud = 134; break;
+ case B150: baud = 150; break;
+ case B200: baud = 200; break;
+ case B300: baud = 300; break;
+ case B600: baud = 600; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ case B230400: baud = 230400; break;
+ case B460800: baud = 460800; break;
+ }
+ if (baud > 0)
+ brg = m8xx_get_brg_clk(baud); /* 4 BRGs, 6 serial ports - hopefully */
+ /* at least 2 ports will be the same */
+
+ /* Number of data bits */
+ switch ( t->c_cflag & CSIZE ) {
+ case CS5: csize = 5; break;
+ case CS6: csize = 6; break;
+ case CS7: csize = 7; break;
+ case CS8: csize = 8; break;
+ }
+
+ /* Stop bits */
+ if ( t->c_cflag & CSTOPB ) {
+ cstopb = 0x0400; /* Two stop bits */
+ ssize = 2;
+ } else {
+ cstopb = 0x0000; /* One stop bit */
+ ssize = 1;
+ }
+
+ /* Parity */
+ if ( t->c_cflag & PARENB ) {
+ parenb = 0x0200; /* Parity enabled on Tx and Rx */
+ psize = 1;
+ } else {
+ parenb = 0x0000; /* No parity on Tx and Rx */
+ psize = 0;
+ }
+
+ if ( t->c_cflag & PARODD )
+ parodd = 0x0000; /* Odd parity */
+ else
+ parodd = 0x0100;
+
+ /*
+ * Character Length = start + data + parity + stop - 1
+ */
+ switch ( 1 + csize + psize + ssize - 1 ) {
+ case 6: clen = 0x3000; break;
+ case 7: clen = 0x3800; break;
+ case 8: clen = 0x4000; break;
+ case 9: clen = 0x4800; break;
+ case 10: clen = 0x5000; break;
+ case 11: clen = 0x5800; break;
+ }
+
+ if ( t->c_cflag & CREAD )
+ cread = 0x0023; /* UART normal operation, enable Rx and Tx */
+ else
+ cread = 0x0021; /* UART normal operation, enable Tx */
+
+ /* Write the SIMODE/SMCMR registers */
+ switch (minor) {
+ case SMC1_MINOR:
+ m8xx.simode = ( (m8xx.simode & 0xffff8fff) | (brg << 12) );
+ m8xx.smc1.smcmr = clen | cstopb | parenb | parodd | cread;
+ break;
+ case SMC2_MINOR:
+ m8xx.simode = ( (m8xx.simode & 0x8fffffff) | (brg << 28) );
+ m8xx.smc2.smcmr = clen | cstopb | parenb | parodd | cread;
+ break;
+ }
+ return 0;
+}
+
+
+static int
+m8xx_scc_set_attributes (int minor, const struct termios *t)
+{
+ int baud, brg;
+ rtems_unsigned16 csize, cstopb, parenb, parodd;
+
+ /* Baud rate */
+ switch (t->c_cflag & CBAUD) {
+ default: baud = -1; break;
+ case B50: baud = 50; break;
+ case B75: baud = 75; break;
+ case B110: baud = 110; break;
+ case B134: baud = 134; break;
+ case B150: baud = 150; break;
+ case B200: baud = 200; break;
+ case B300: baud = 300; break;
+ case B600: baud = 600; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ case B230400: baud = 230400; break;
+ case B460800: baud = 460800; break;
+ }
+ if (baud > 0)
+ brg = m8xx_get_brg_clk(baud); /* 4 BRGs, 5 serial ports - hopefully */
+ /* at least 2 ports will be the same */
+ /* Write the SICR register below */
+
+ /* Number of data bits */
+ switch ( t->c_cflag & CSIZE ) {
+ case CS5: csize = 0x0000; break;
+ case CS6: csize = 0x1000; break;
+ case CS7: csize = 0x2000; break;
+ case CS8: csize = 0x3000; break;
+ }
+
+ /* Stop bits */
+ if ( t->c_cflag & CSTOPB )
+ cstopb = 0x4000; /* Two stop bits */
+ else
+ cstopb = 0x0000; /* One stop bit */
+
+ /* Parity */
+ if ( t->c_cflag & PARENB )
+ parenb = 0x0010; /* Parity enabled on Tx and Rx */
+ else
+ parenb = 0x0000; /* No parity on Tx and Rx */
+
+ if ( t->c_cflag & PARODD )
+ parodd = 0x0000; /* Odd parity */
+ else
+ parodd = 0x000a;
+
+ /* Write the SICR/PSMR Registers */
+ switch (minor) {
+ case SCC2_MINOR:
+ m8xx.sicr = ( (m8xx.sicr & 0xffffc0ff) | (brg << 11) | (brg << 8) );
+ m8xx.scc2.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc2.psmr & 0x8fe0) );
+ break;
+ #if defined(mpc860)
+ case SCC3_MINOR:
+ m8xx.sicr = ( (m8xx.sicr & 0xffc0ffff) | (brg << 19) | (brg << 16) );
+ m8xx.scc3.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc3.psmr & 0x8fe0) );
+ break;
+ case SCC4_MINOR:
+ m8xx.sicr = ( (m8xx.sicr & 0xc0ffffff) | (brg << 27) | (brg << 24) );
+ m8xx.scc4.psmr = ( (cstopb | csize | parenb | parodd) | (m8xx.scc4.psmr & 0x8fe0) );
+ break;
+ #endif
+ }
+
+ return 0;
+}
+
+
+int
+m8xx_uart_setAttributes(
+ int minor,
+ const struct termios *t
+)
+{
+ /*
+ * Check that port number is valid
+ */
+ if ( (minor < SMC1_MINOR) || (minor > NUM_PORTS-1) )
+ return 0;
+
+ switch (minor) {
+ case SMC1_MINOR:
+ case SMC2_MINOR:
+ return m8xx_smc_set_attributes( minor, t );
+
+ case SCC2_MINOR:
+ case SCC3_MINOR:
+ case SCC4_MINOR:
+ return m8xx_scc_set_attributes( minor, t );
+ }
+ return 0;
+}
+
+
+/*
+ * Interrupt handlers
+ */
+static rtems_isr
+m8xx_scc2_interrupt_handler (rtems_vector_number v)
+{
+ int nb_overflow;
+
+ /*
+ * Buffer received?
+ */
+ if ((m8xx.scc2.sccm & M8xx_SCCE_RX) && (m8xx.scc2.scce & M8xx_SCCE_RX)) {
+ m8xx.scc2.scce = M8xx_SCCE_RX; /* Clear the event */
+
+
+ /* Check that the buffer is ours */
+ if ((RxBd[SCC2_MINOR]->status & M8xx_BD_EMPTY) == 0) {
+ rtems_invalidate_multiple_data_cache_lines(
+ RxBd[SCC2_MINOR]->buffer,
+ RxBd[SCC2_MINOR]->length );
+ nb_overflow = rtems_termios_enqueue_raw_characters(
+ (void *)ttyp[SCC2_MINOR],
+ (char *)RxBd[SCC2_MINOR]->buffer,
+ (int)RxBd[SCC2_MINOR]->length );
+ RxBd[SCC2_MINOR]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP |
+ M8xx_BD_INTERRUPT;
+ }
+ }
+
+ /*
+ * Buffer transmitted?
+ */
+ if (m8xx.scc2.scce & M8xx_SCCE_TX) {
+ m8xx.scc2.scce = M8xx_SCCE_TX; /* Clear the event */
+
+ /* Check that the buffer is ours */
+ if ((TxBd[SCC2_MINOR]->status & M8xx_BD_READY) == 0)
+ rtems_termios_dequeue_characters (
+ (void *)ttyp[SCC2_MINOR],
+ (int)TxBd[SCC2_MINOR]->length);
+ }
+ m8xx.cisr = 1UL << 29; /* Clear SCC2 interrupt-in-service bit */
+}
+
+
+#ifdef mpc860
+static rtems_isr
+m8xx_scc3_interrupt_handler (rtems_vector_number v)
+{
+ int nb_overflow;
+
+ /*
+ * Buffer received?
+ */
+ if ((m8xx.scc3.sccm & M8xx_SCCE_RX) && (m8xx.scc3.scce & M8xx_SCCE_RX)) {
+ m8xx.scc3.scce = M8xx_SCCE_RX; /* Clear the event */
+
+
+ /* Check that the buffer is ours */
+ if ((RxBd[SCC3_MINOR]->status & M8xx_BD_EMPTY) == 0) {
+ rtems_invalidate_multiple_data_cache_lines(
+ RxBd[SCC3_MINOR]->buffer,
+ RxBd[SCC3_MINOR]->length );
+ nb_overflow = rtems_termios_enqueue_raw_characters(
+ (void *)ttyp[SCC3_MINOR],
+ (char *)RxBd[SCC3_MINOR]->buffer,
+ (int)RxBd[SCC3_MINOR]->length );
+ RxBd[SCC3_MINOR]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP |
+ M8xx_BD_INTERRUPT;
+ }
+ }
+
+ /*
+ * Buffer transmitted?
+ */
+ if (m8xx.scc3.scce & M8xx_SCCE_TX) {
+ m8xx.scc3.scce = M8xx_SCCE_TX; /* Clear the event */
+
+ /* Check that the buffer is ours */
+ if ((TxBd[SCC3_MINOR]->status & M8xx_BD_READY) == 0)
+ rtems_termios_dequeue_characters (
+ (void *)ttyp[SCC3_MINOR],
+ (int)TxBd[SCC3_MINOR]->length);
+ }
+ m8xx.cisr = 1UL << 28; /* Clear SCC3 interrupt-in-service bit */
+}
+
+
+static rtems_isr
+m8xx_scc4_interrupt_handler (rtems_vector_number v)
+{
+ int nb_overflow;
+
+ /*
+ * Buffer received?
+ */
+ if ((m8xx.scc4.sccm & M8xx_SCCE_RX) && (m8xx.scc4.scce & M8xx_SCCE_RX)) {
+ m8xx.scc4.scce = M8xx_SCCE_RX; /* Clear the event */
+
+
+ /* Check that the buffer is ours */
+ if ((RxBd[SCC4_MINOR]->status & M8xx_BD_EMPTY) == 0) {
+ rtems_invalidate_multiple_data_cache_lines(
+ RxBd[SCC4_MINOR]->buffer,
+ RxBd[SCC4_MINOR]->length );
+ nb_overflow = rtems_termios_enqueue_raw_characters(
+ (void *)ttyp[SCC4_MINOR],
+ (char *)RxBd[SCC4_MINOR]->buffer,
+ (int)RxBd[SCC4_MINOR]->length );
+ RxBd[SCC4_MINOR]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP |
+ M8xx_BD_INTERRUPT;
+ }
+ }
+
+ /*
+ * Buffer transmitted?
+ */
+ if (m8xx.scc4.scce & M8xx_SCCE_TX) {
+ m8xx.scc4.scce = M8xx_SCCE_TX; /* Clear the event */
+
+ /* Check that the buffer is ours */
+ if ((TxBd[SCC4_MINOR]->status & M8xx_BD_READY) == 0)
+ rtems_termios_dequeue_characters (
+ (void *)ttyp[SCC4_MINOR],
+ (int)TxBd[SCC4_MINOR]->length);
+ }
+ m8xx.cisr = 1UL << 27; /* Clear SCC4 interrupt-in-service bit */
+}
+#endif
+
+static rtems_isr
+m8xx_smc1_interrupt_handler (rtems_vector_number v)
+{
+ int nb_overflow;
+
+ /*
+ * Buffer received?
+ */
+ if (m8xx.smc1.smce & M8xx_SMCE_RX) {
+ m8xx.smc1.smce = M8xx_SMCE_RX; /* Clear the event */
+
+
+ /* Check that the buffer is ours */
+ if ((RxBd[SMC1_MINOR]->status & M8xx_BD_EMPTY) == 0) {
+ rtems_invalidate_multiple_data_cache_lines(
+ RxBd[SMC1_MINOR]->buffer,
+ RxBd[SMC1_MINOR]->length );
+ nb_overflow = rtems_termios_enqueue_raw_characters(
+ (void *)ttyp[SMC1_MINOR],
+ (char *)RxBd[SMC1_MINOR]->buffer,
+ (int)RxBd[SMC1_MINOR]->length );
+ RxBd[SMC1_MINOR]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP |
+ M8xx_BD_INTERRUPT;
+ }
+ }
+
+ /*
+ * Buffer transmitted?
+ */
+ if (m8xx.smc1.smce & M8xx_SMCE_TX) {
+ m8xx.smc1.smce = M8xx_SMCE_TX; /* Clear the event */
+
+ /* Check that the buffer is ours */
+ if ((TxBd[SMC1_MINOR]->status & M8xx_BD_READY) == 0)
+ rtems_termios_dequeue_characters (
+ (void *)ttyp[SMC1_MINOR],
+ (int)TxBd[SMC1_MINOR]->length);
+ }
+ m8xx.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */
+}
+
+
+static rtems_isr
+m8xx_smc2_interrupt_handler (rtems_vector_number v)
+{
+ int nb_overflow;
+
+ /*
+ * Buffer received?
+ */
+ if (m8xx.smc2.smce & M8xx_SMCE_RX) {
+ m8xx.smc2.smce = M8xx_SMCE_RX; /* Clear the event */
+
+
+ /* Check that the buffer is ours */
+ if ((RxBd[SMC2_MINOR]->status & M8xx_BD_EMPTY) == 0) {
+ rtems_invalidate_multiple_data_cache_lines(
+ RxBd[SMC2_MINOR]->buffer,
+ RxBd[SMC2_MINOR]->length );
+ nb_overflow = rtems_termios_enqueue_raw_characters(
+ (void *)ttyp[SMC2_MINOR],
+ (char *)RxBd[SMC2_MINOR]->buffer,
+ (int)RxBd[SMC2_MINOR]->length );
+ RxBd[SMC2_MINOR]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP |
+ M8xx_BD_INTERRUPT;
+ }
+ }
+
+ /*
+ * Buffer transmitted?
+ */
+ if (m8xx.smc2.smce & M8xx_SMCE_TX) {
+ m8xx.smc2.smce = M8xx_SMCE_TX; /* Clear the event */
+
+ /* Check that the buffer is ours */
+ if ((TxBd[SMC2_MINOR]->status & M8xx_BD_READY) == 0)
+ rtems_termios_dequeue_characters (
+ (void *)ttyp[SMC2_MINOR],
+ (int)TxBd[SMC2_MINOR]->length);
+ }
+ m8xx.cisr = 1UL << 3; /* Clear SMC2 interrupt-in-service bit */
+}
+
+
+void
+m8xx_uart_scc_initialize (int minor)
+{
+ unsigned char brg;
+ volatile m8xxSCCparms_t *sccparms;
+ volatile m8xxSCCRegisters_t *sccregs;
+
+ /*
+ * Check that minor number is valid
+ */
+ if ( (minor < SCC2_MINOR) || (minor > NUM_PORTS-1) )
+ return;
+
+ /* Get the sicr clock source bit values for 9600 bps */
+ brg = m8xx_get_brg_clk(9600);
+
+ /*
+ * Allocate buffer descriptors
+ */
+ RxBd[minor] = m8xx_bd_allocate(1);
+ TxBd[minor] = m8xx_bd_allocate(1);
+
+ /*
+ * Get the address of the parameter RAM for the specified port,
+ * configure I/O port A,C & D and put SMC in NMSI mode, connect
+ * the SCC to the appropriate BRG.
+ *
+ * SCC2 TxD is shared with port A bit 12
+ * SCC2 RxD is shared with port A bit 13
+ * SCC1 TxD is shared with port A bit 14
+ * SCC1 RxD is shared with port A bit 15
+ * SCC4 DCD is shared with port C bit 4
+ * SCC4 CTS is shared with port C bit 5
+ * SCC3 DCD is shared with port C bit 6
+ * SCC3 CTS is shared with port C bit 7
+ * SCC2 DCD is shared with port C bit 8
+ * SCC2 CTS is shared with port C bit 9
+ * SCC1 DCD is shared with port C bit 10
+ * SCC1 CTS is shared with port C bit 11
+ * SCC2 RTS is shared with port C bit 14
+ * SCC1 RTS is shared with port C bit 15
+ * SCC4 RTS is shared with port D bit 6
+ * SCC3 RTS is shared with port D bit 7
+ * SCC4 TxD is shared with port D bit 8
+ * SCC4 RxD is shared with port D bit 9
+ * SCC3 TxD is shared with port D bit 10
+ * SCC3 RxD is shared with port D bit 11
+ */
+ switch (minor) {
+ case SCC2_MINOR:
+ sccparms = &m8xx.scc2p;
+ sccregs = &m8xx.scc2;
+
+ m8xx.papar |= 0x000C; /* PA12 & PA13 are dedicated peripheral pins */
+ m8xx.padir &= ~0x000C; /* PA13 & PA12 must not drive the UART lines */
+ m8xx.paodr &= ~0x000C; /* PA12 & PA13 are not open drain */
+ m8xx.pcpar |= 0x0002; /* PC14 is SCC2 RTS */
+ m8xx.pcpar &= ~0x00C0; /* PC8 & PC9 are SCC2 DCD and CTS */
+ m8xx.pcdir &= ~0x00C2; /* PC8, PC9 & PC14 must not drive the UART lines */
+ m8xx.pcso |= 0x00C0; /* Enable DCD and CTS inputs */
+
+ m8xx.sicr &= 0xFFFF00FF; /* Clear TCS2 & RCS2, GR2=no grant, SC2=NMSI mode */
+ m8xx.sicr |= (brg<<11) | (brg<<8); /* TCS2 = RCS2 = brg */
+ break;
+
+#ifdef mpc860
+ case SCC3_MINOR:
+ sccparms = &m8xx.scc3p;
+ sccregs = &m8xx.scc3;
+
+ m8xx.pcpar &= ~0x0300; /* PC6 & PC7 are SCC3 DCD and CTS */
+ m8xx.pcdir &= ~0x0300; /* PC6 & PC7 must not drive the UART lines */
+ m8xx.pcso |= 0x0300; /* Enable DCD and CTS inputs */
+ m8xx.pdpar |= 0x0130; /* PD7, PD10 & PD11 are dedicated peripheral pins */
+
+ m8xx.sicr &= 0xFF00FFFF; /* Clear TCS3 & RCS3, GR3=no grant, SC3=NMSI mode */
+ m8xx.sicr |= (brg<<19) | (brg<<16); /* TCS3 = RCS3 = brg */
+ break;
+
+ case SCC4_MINOR:
+ sccparms = &m8xx.scc4p;
+ sccregs = &m8xx.scc4;
+
+ m8xx.pcpar &= ~0x0C00; /* PC4 & PC5 are SCC4 DCD and CTS */
+ m8xx.pcdir &= ~0x0C00; /* PC4 & PC5 must not drive the UART lines */
+ m8xx.pcso |= 0x0C00; /* Enable DCD and CTS inputs */
+ m8xx.pdpar |= 0x02C0; /* PD6, PD8 & PD9 are dedicated peripheral pins */
+
+ m8xx.sicr &= 0x00FFFFFF; /* Clear TCS4 & RCS4, GR4=no grant, SC4=NMSI mode */
+ m8xx.sicr |= (brg<<27) | (brg<<24); /* TCS4 = RCS4 = brg */
+ break;
+#endif
+ }
+
+ /*
+ * Set up SDMA
+ */
+ m8xx.sdcr = 0x01; /* as per section 16.10.2.1 MPC821UM/AD */
+
+ /*
+ * Set up the SCC parameter RAM.
+ */
+ sccparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
+ sccparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;
+
+ sccparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
+ sccparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
+#ifdef UARTS_USE_INTERRUPTS
+ sccparms->mrblr = RXBUFSIZE; /* Maximum Rx buffer size */
+#else
+ sccparms->mrblr = 1; /* Maximum Rx buffer size */
+#endif
+
+ sccparms->un.uart.max_idl = 10; /* Set nb of idle chars to close buffer */
+ sccparms->un.uart.brkcr = 0; /* Set nb of breaks to send for STOP Tx */
+
+ sccparms->un.uart.parec = 0; /* Clear parity error counter */
+ sccparms->un.uart.frmec = 0; /* Clear framing error counter */
+ sccparms->un.uart.nosec = 0; /* Clear noise counter */
+ sccparms->un.uart.brkec = 0; /* Clear break counter */
+
+ sccparms->un.uart.uaddr[0] = 0; /* Not in multidrop mode, so clear */
+ sccparms->un.uart.uaddr[1] = 0; /* Not in multidrop mode, so clear */
+ sccparms->un.uart.toseq = 0; /* Tx Out-Of-SEQuence--no XON/XOFF now */
+
+ sccparms->un.uart.character[0] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[1] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[2] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[3] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[4] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[5] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[6] = 0x8000; /* Entry is invalid */
+ sccparms->un.uart.character[7] = 0x8000; /* Entry is invalid */
+
+
+ sccparms->un.uart.rccm = 0xc0ff; /* No masking */
+
+ /*
+ * Set up the Receive Buffer Descriptor
+ */
+ RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
+ RxBd[minor]->length = 0;
+ RxBd[minor]->buffer = rxBuf[minor];
+
+ /*
+ * Setup the Transmit Buffer Descriptor
+ */
+ TxBd[minor]->status = M8xx_BD_WRAP;
+
+ /*
+ * Set up SCCx general and protocol-specific mode registers
+ */
+ sccregs->gsmr_h = 0x00000020; /* RFW=low latency operation */
+ sccregs->gsmr_l = 0x00028004; /* TDCR=RDCR=16x clock mode, MODE=uart*/
+ sccregs->scce = ~0; /* Clear any pending event */
+ sccregs->sccm = 0; /* Mask all interrupt/event sources */
+ sccregs->psmr = 0x3000; /* Normal operation & mode, 1 stop bit,
+ 8 data bits, no parity */
+ sccregs->dsr = 0x7E7E; /* No fractional stop bits */
+ sccregs->gsmr_l = 0x00028034; /* ENT=enable Tx, ENR=enable Rx */
+
+ /*
+ * Initialize the Rx and Tx with the new parameters.
+ */
+ switch (minor) {
+ case SCC2_MINOR:
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC2);
+ break;
+
+#ifdef mpc860
+ case SCC3_MINOR:
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC3);
+ break;
+ case SCC4_MINOR:
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC4);
+ break;
+#endif
+ }
+#ifdef UARTS_USE_INTERRUPTS
+ switch (minor) {
+ case SCC2_MINOR:
+ rtems_interrupt_catch (m8xx_scc2_interrupt_handler,
+ PPC_IRQ_CPM_SCC2,
+ &old_handler[minor]);
+
+ sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
+ m8xx.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
+ break;
+
+#ifdef mpc860
+ case SCC3_MINOR:
+ rtems_interrupt_catch (m8xx_scc3_interrupt_handler,
+ PPC_IRQ_CPM_SCC3,
+ &old_handler[minor]);
+
+ sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
+ m8xx.cimr |= 1UL << 28; /* Enable SCC2 interrupts */
+ break;
+
+ case SCC4_MINOR:
+ rtems_interrupt_catch (m8xx_scc4_interrupt_handler,
+ PPC_IRQ_CPM_SCC4,
+ &old_handler[minor]);
+
+ sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */
+ m8xx.cimr |= 1UL << 27; /* Enable SCC2 interrupts */
+ break;
+#endif /* mpc860 */
+ }
+#endif /* UARTS_USE_INTERRUPTS */
+}
+
+
+void
+m8xx_uart_smc_initialize (int minor)
+{
+ unsigned char brg;
+ volatile m8xxSMCparms_t *smcparms;
+ volatile m8xxSMCRegisters_t *smcregs;
+
+ /*
+ * Check that minor number is valid
+ */
+ if ( (minor < SMC1_MINOR) || (minor > SMC2_MINOR) )
+ return;
+
+ /* Get the simode clock source bit values for 9600 bps */
+ brg = m8xx_get_brg_clk(9600);
+
+ /*
+ * Allocate buffer descriptors
+ */
+ RxBd[minor] = m8xx_bd_allocate (1);
+ TxBd[minor] = m8xx_bd_allocate (1);
+
+ /*
+ * Get the address of the parameter RAM for the specified port,
+ * configure I/O port B and put SMC in NMSI mode, connect the
+ * SMC to the appropriate BRG.
+ *
+ * SMC2 RxD is shared with port B bit 20
+ * SMC2 TxD is shared with port B bit 21
+ * SMC1 RxD is shared with port B bit 24
+ * SMC1 TxD is shared with port B bit 25
+ */
+ switch (minor) {
+ case SMC1_MINOR:
+ smcparms = &m8xx.smc1p;
+ smcregs = &m8xx.smc1;
+
+ m8xx.pbpar |= 0x000000C0; /* PB24 & PB25 are dedicated peripheral pins */
+ m8xx.pbdir &= ~0x000000C0; /* PB24 & PB25 must not drive UART lines */
+ m8xx.pbodr &= ~0x000000C0; /* PB24 & PB25 are not open drain */
+
+ m8xx.simode &= 0xFFFF0FFF; /* Clear SMC1CS & SMC1 for NMSI mode */
+ m8xx.simode |= brg << 12; /* SMC1CS = brg */
+ break;
+
+ case SMC2_MINOR:
+ smcparms = &m8xx.smc2p;
+ smcregs = &m8xx.smc2;
+
+ m8xx.pbpar |= 0x00000C00; /* PB20 & PB21 are dedicated peripheral pins */
+ m8xx.pbdir &= ~0x00000C00; /* PB20 & PB21 must not drive the UART lines */
+ m8xx.pbodr &= ~0x00000C00; /* PB20 & PB21 are not open drain */
+
+ m8xx.simode &= 0x0FFFFFFF; /* Clear SMC2CS & SMC2 for NMSI mode */
+ m8xx.simode |= brg << 28; /* SMC2CS = brg */
+ break;
+ }
+
+ /*
+ * Set up SMC1 parameter RAM common to all protocols
+ */
+ smcparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
+ smcparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;
+ smcparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
+ smcparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
+#ifdef UARTS_USE_INTERRUPTS
+ smcparms->mrblr = RXBUFSIZE; /* Maximum Rx buffer size */
+#else
+ smcparms->mrblr = 1; /* Maximum Rx buffer size */
+#endif
+
+ /*
+ * Set up SMC1 parameter RAM UART-specific parameters
+ */
+ smcparms->un.uart.max_idl = 10; /* Set nb of idle chars to close buffer */
+ smcparms->un.uart.brkcr = 0; /* Set nb of breaks to send for STOP Tx */
+ smcparms->un.uart.brkec = 0; /* Clear break counter */
+
+ /*
+ * Set up the Receive Buffer Descriptor
+ */
+ RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
+ RxBd[minor]->length = 0;
+ RxBd[minor]->buffer = rxBuf[minor];
+
+ /*
+ * Setup the Transmit Buffer Descriptor
+ */
+ TxBd[minor]->status = M8xx_BD_WRAP;
+
+ /*
+ * Set up SMCx general and protocol-specific mode registers
+ */
+ smcregs->smce = ~0; /* Clear any pending events */
+ smcregs->smcm = 0; /* Enable SMC Rx & Tx interrupts */
+ smcregs->smcmr = M8xx_SMCMR_CLEN(9) | M8xx_SMCMR_SM_UART;
+
+ /*
+ * Send "Init parameters" command
+ */
+ switch (minor) {
+ case SMC1_MINOR:
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC1);
+ break;
+
+ case SMC2_MINOR:
+ m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC2);
+ break;
+ }
+
+ /*
+ * Enable receiver and transmitter
+ */
+ smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN;
+#ifdef UARTS_USE_INTERRUPTS
+ switch (minor) {
+ case SMC1_MINOR:
+ rtems_interrupt_catch (m8xx_smc1_interrupt_handler,
+ PPC_IRQ_CPM_SMC1,
+ &old_handler[minor]);
+
+ smcregs->smcm = 3; /* Enable SMC1 Rx & Tx interrupts */
+ m8xx.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
+ break;
+
+ case SMC2_MINOR:
+ rtems_interrupt_catch (m8xx_smc2_interrupt_handler,
+ PPC_IRQ_CPM_SMC2,
+ &old_handler[minor]);
+
+ smcregs->smcm = 3; /* Enable SMC2 Rx & Tx interrupts */
+ m8xx.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
+ break;
+ }
+#endif
+}
+
+void
+m8xx_uart_initialize(void)
+{
+ int i;
+
+ for (i=0; i < 4; i++) {
+ brg_spd[i] = 0;
+ brg_used[i] = 0;
+ }
+}
+
+
+void
+m8xx_uart_interrupts_initialize(void)
+{
+#ifdef mpc860
+ m8xx.cicr = 0x00E43F80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
+ SCdP=SCC4, IRL=1, HP=PC15, IEN=1 */
+#else
+ m8xx.cicr = 0x00043F80; /* SCaP=SCC1, SCbP=SCC2, IRL=1, HP=PC15, IEN=1 */
+#endif
+#ifdef EPPCBUG_SMC1
+ simask_copy = m8xx.simask | M8xx_SIMASK_LVM1;
+#endif /* EPPCBUG_SMC1 */
+ m8xx.simask |= M8xx_SIMASK_LVM1; /* Enable level interrupts */
+}
+
+
+int
+m8xx_uart_pollRead(
+ int minor
+)
+{
+ unsigned char c;
+
+ if (RxBd[minor]->status & M8xx_BD_EMPTY) {
+ return -1;
+ }
+ _CPU_Data_Cache_Block_Invalidate( RxBd[minor]->buffer );
+ c = ((char *)RxBd[minor]->buffer)[0];
+ RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP;
+ return c;
+}
+
+
+/*
+ * TODO: Get a free buffer and set it up.
+ */
+int
+m8xx_uart_write(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ rtems_flush_multiple_data_cache_lines( buf, len );
+ TxBd[minor]->buffer = (char *) buf;
+ TxBd[minor]->length = len;
+ TxBd[minor]->status = M8xx_BD_READY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
+ return 0;
+}
+
+
+int
+m8xx_uart_pollWrite(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ while (len--) {
+ while (TxBd[minor]->status & M8xx_BD_READY)
+ continue;
+ txBuf[minor] = *buf++;
+ _CPU_Data_Cache_Block_Flush( &txBuf[minor] );
+ TxBd[minor]->buffer = &txBuf[minor];
+ TxBd[minor]->length = 1;
+ TxBd[minor]->status = M8xx_BD_READY | M8xx_BD_WRAP;
+ }
+ return 0;
+}
+
+void
+m8xx_uart_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources (configuration, NUM_PORTS);
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am
new file mode 100644
index 0000000000..1c9af7e4a3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/Makefile.am
@@ -0,0 +1,38 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/cp.rel
+
+## C sources
+C_FILES = cp.c dpram.c
+
+clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(clock_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c
new file mode 100644
index 0000000000..235e4bafc3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/cp.c
@@ -0,0 +1,34 @@
+/*
+ * cp.c
+ *
+ * MPC8xx CPM RISC Communication Processor routines.
+ *
+ * Based on code (alloc860.c in eth_comm port) by
+ * Jay Monkman (jmonkman@frasca.com),
+ * which, in turn, is based on code by
+ * W. Eric Norum (eric@skatter.usask.ca).
+ *
+ * Modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include <bsp.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/error.h>
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+void m8xx_cp_execute_cmd( unsigned16 command )
+{
+ rtems_unsigned16 lvl;
+
+ rtems_interrupt_disable(lvl);
+ while (m8xx.cpcr & M8xx_CR_FLG) {
+ continue;
+ }
+
+ m8xx.cpcr = command | M8xx_CR_FLG;
+ rtems_interrupt_enable (lvl);
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c
new file mode 100644
index 0000000000..985b5b5bd1
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/cpm/dpram.c
@@ -0,0 +1,89 @@
+/*
+ * dpram.c
+ *
+ * MPC8xx dual-port RAM allocation routines
+ *
+ * Based on code (alloc860.c in eth_comm port) by
+ * Jay Monkman (jmonkman@frasca.com),
+ * which, in turn, is based on code by
+ * W. Eric Norum (eric@skatter.usask.ca).
+ *
+ *
+ * Modifications :
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include <bsp.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/error.h>
+
+/*
+ * Allocation order:
+ * - Dual-Port RAM section 0
+ * - Dual-Port RAM section 1
+ * - Dual-Port RAM section 2
+ * - Dual-Port RAM section 3
+ * - Dual-Port RAM section 4
+ */
+static struct {
+ unsigned8 *base;
+ unsigned int size;
+ unsigned int used;
+} dpram_regions[] = {
+ { (char *)&m8xx.dpram0[0], sizeof m8xx.dpram0, 0 },
+ { (char *)&m8xx.dpram1[0], sizeof m8xx.dpram1, 0 },
+ { (char *)&m8xx.dpram2[0], sizeof m8xx.dpram2, 0 },
+ { (char *)&m8xx.dpram3[0], sizeof m8xx.dpram3, 0 },
+ { (char *)&m8xx.dpram4[0], sizeof m8xx.dpram4, 0 },
+};
+
+#define NUM_DPRAM_REGIONS (sizeof(dpram_regions) / sizeof(dpram_regions[0]))
+
+void *
+m8xx_dpram_allocate( unsigned int byte_count )
+{
+ unsigned int i;
+ ISR_Level level;
+ void *blockp = NULL;
+
+ byte_count = (byte_count + 3) & ~0x3;
+
+ /*
+ * Running with interrupts disabled is usually considered bad
+ * form, but this routine is probably being run as part of an
+ * initialization sequence so the effect shouldn't be too severe.
+ */
+ _ISR_Disable (level);
+
+ for ( i = 0; i < NUM_DPRAM_REGIONS; i++ ) {
+ /*
+ * Verify that the region is available for use.
+ * This test is necessary because if extra microcode modules
+ * are installed, some regions are locked and unavailable.
+ * See MPC860 User's Manual Pages 19-9 to 19-11.
+ */
+ if (dpram_regions[i].used == 0) {
+ volatile unsigned char *cp = dpram_regions[i].base;
+ *cp = 0xAA;
+ if (*cp != 0xAA)
+ dpram_regions[i].used = dpram_regions[i].size;
+ else {
+ *cp = 0x55;
+ if (*cp != 0x55)
+ dpram_regions[i].used = dpram_regions[i].size;
+ }
+ *cp = 0x0;
+ }
+ if (dpram_regions[i].size - dpram_regions[i].used >= byte_count) {
+ blockp = dpram_regions[i].base + dpram_regions[i].used;
+ dpram_regions[i].used += byte_count;
+ break;
+ }
+ }
+
+ _ISR_Enable(level);
+
+ if (blockp == NULL)
+ rtems_panic("Can't allocate %d bytes of dual-port RAM.\n", byte_count);
+ return blockp;
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/include/Makefile.am
new file mode 100644
index 0000000000..eb400375c0
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/Makefile.am
@@ -0,0 +1,28 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+H_FILES = mpc8xx.h
+MPC8XX_H_FILES = console.h cpm.h mmu.h
+
+noinst_HEADERS = $(H_FILES) $(MPC8XX_H_FILES)
+
+PREINSTALL_FILES = \
+$(PROJECT_INCLUDE)/mpc8xx \
+$(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h) \
+$(MPC8XX_H_FILES:%.h=$(PROJECT_INCLUDE)/mpc8xx/%.h)
+
+$(PROJECT_INCLUDE)/mpc8xx:
+ $(mkinstalldirs) $@
+
+$(PROJECT_INCLUDE)/%.h: %.h
+ $(INSTALL_DATA) $< $@
+
+$(PROJECT_INCLUDE)/mpc8xx/%.h: %.h
+ $(INSTALL_DATA) $< $@
+
+all-local: $(PREINSTALL_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/console.h b/c/src/lib/libcpu/powerpc/mpc8xx/include/console.h
new file mode 100644
index 0000000000..0835545a46
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/console.h
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ */
+
+#ifndef _M8xx_CONSOLE_H_
+#define _M8xx_CONSOLE_H_
+
+#include <rtems/libio.h>
+
+void m8xx_uart_reserve_resources(rtems_configuration_table *configuration);
+void m8xx_uart_initialize(void);
+void m8xx_uart_interrupts_initialize(void);
+void m8xx_uart_scc_initialize (int minor);
+void m8xx_uart_smc_initialize (int minor);
+
+/* Termios callbacks */
+int m8xx_uart_pollRead(int minor);
+int m8xx_uart_pollWrite(int minor, const char* buf, int len);
+int m8xx_uart_write(int minor, const char *buf, int len);
+int m8xx_uart_setAttributes(int, const struct termios* t);
+
+
+#ifdef mpc860
+#define NUM_PORTS 6 /* number of serial ports for mpc860 */
+#else
+#define NUM_PORTS 4 /* number of serial ports for mpc821 */
+#endif
+
+#define SMC1_MINOR 0
+#define SMC2_MINOR 1
+#define SCC1_MINOR 2
+#define SCC2_MINOR 3
+#define SCC3_MINOR 4
+#define SCC4_MINOR 5
+
+
+#endif
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/cpm.h b/c/src/lib/libcpu/powerpc/mpc8xx/include/cpm.h
new file mode 100644
index 0000000000..d39ddf2e23
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/cpm.h
@@ -0,0 +1,38 @@
+/*
+ * cpm.h
+ *
+ * This include file contains definitions pertaining
+ * to the Communications Processor Module (CPM) on the MPC8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#ifndef __M8xx_CPM_h
+#define __M8xx_CPM_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bsp.h>
+
+/* Functions */
+
+void m8xx_cp_execute_cmd( unsigned16 command );
+void *m8xx_dpram_allocate( unsigned int byte_count );
+
+#define m8xx_bd_allocate(count) \
+ m8xx_dpram_allocate( (count) * sizeof(m8xxBufferDescriptor_t) )
+#define m8xx_RISC_timer_table_allocate(count) \
+ m8xx_dpram_allocate( (count) * 4 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/mmu.h b/c/src/lib/libcpu/powerpc/mpc8xx/include/mmu.h
new file mode 100644
index 0000000000..7370e0cf5a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/mmu.h
@@ -0,0 +1,49 @@
+/*
+ * mmu.h
+ *
+ * This include file contains definitions pertaining
+ * to the MMU on the MPC8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#ifndef __M8xx_MMU_h
+#define __M8xx_MMU_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bsp.h>
+
+/*
+ * The MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of an MPC8xx.
+ */
+typedef struct {
+ unsigned32 mmu_epn; /* Effective Page Number */
+ unsigned32 mmu_twc; /* Tablewalk Control Register */
+ unsigned32 mmu_rpn; /* Real Page Number */
+} MMU_TLB_table_t;
+
+/*
+ * The MMU_TLB_table and its size, MMU_N_TLB_Table_Entries, must be
+ * supplied by the BSP.
+ */
+extern MMU_TLB_table_t MMU_TLB_table[]; /* MMU TLB table supplied by BSP */
+extern int MMU_N_TLB_Table_Entries; /* Number of entries in MMU TLB table */
+
+/* Functions */
+
+void mmu_init( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h b/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h
new file mode 100644
index 0000000000..566b617baf
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h
@@ -0,0 +1,1399 @@
+/*
+**************************************************************************
+**************************************************************************
+** **
+** MOTOROLA MPC860/MPC821 PORTABLE SYSTEMS MICROPROCESSOR **
+** **
+** HARDWARE DECLARATIONS **
+** **
+** **
+** Submitted By: **
+** **
+** W. Eric Norum **
+** Saskatchewan Accelerator Laboratory **
+** University of Saskatchewan **
+** 107 North Road **
+** Saskatoon, Saskatchewan, CANADA **
+** S7N 5C6 **
+** **
+** eric@skatter.usask.ca **
+** **
+** Modified for use with the MPC860 (original code was for MC68360) **
+** by **
+** Jay Monkman **
+** Frasca International, Inc. **
+** 906 E. Airport Rd. **
+** Urbana, IL, 61801 **
+** **
+** jmonkman@frasca.com **
+** **
+** Modified further for use with the MPC821 by: **
+** Andrew Bray <andy@chaos.org.uk> **
+** **
+** With some corrections/additions by: **
+** Darlene A. Stewart and **
+** Charles-Antoine Gauthier **
+** Institute for Information Technology **
+** National Research Council of Canada **
+** Ottawa, ON K1A 0R6 **
+** **
+** Darlene.Stewart@iit.nrc.ca **
+** charles.gauthier@iit.nrc.ca **
+** **
+** Corrections/additions: **
+** Copyright (c) 1999, National Research Council of Canada **
+**************************************************************************
+**************************************************************************
+*/
+
+#ifndef __MPC8xx_h
+#define __MPC8xx_h
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Macros for accessing Special Purpose Registers (SPRs)
+ */
+#define _mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
+#define _mfspr(_reg,_spr) __asm__ volatile ( "mfspr %0, %1\n" : "=r" ((_reg)) : "i" ((_spr)) )
+
+#define _isync __asm__ volatile ("isync\n"::)
+
+/*
+ * Core Registers (SPRs)
+ */
+#define M8xx_DEC 22 /* Decrementer Register */
+#define M8xx_DER 149 /* Debug Enable Register */
+#define M8xx_ICTRL 158 /* Instruction Support Control Register */
+#define M8xx_TBL_WR 284 /* Timebase Lower Write Register */
+#define M8xx_TBU_WR 285 /* Timebase Upper Write Register */
+#define M8xx_IMMR 638 /* Internal Memory Map Register */
+
+/*
+ * Cache Control Registers (SPRs)
+ */
+#define M8xx_IC_CST 560 /* Instruction Cache Control and Status Register */
+#define M8xx_DC_CST 568 /* Data Cache Control and Status Register */
+#define M8xx_IC_ADR 561 /* Instruction Cache Address Register */
+#define M8xx_DC_ADR 569 /* Data Cache Address Register */
+#define M8xx_IC_DAT 562 /* Instruction Cache Data Port Register */
+#define M8xx_DC_DAT 570 /* Data Cache Data Port Register */
+
+/*
+ * MMU Registers (SPRs)
+ */
+/* Control Registers */
+#define M8xx_MI_CTR 784 /* IMMU Control Register */
+#define M8xx_MD_CTR 792 /* DMMU Control Register */
+/* TLB Source Registers */
+#define M8xx_MI_EPN 787 /* IMMU Effective Page Number Register (EPN) */
+#define M8xx_MD_EPN 795 /* DMMU Effective Page Number Register (EPN) */
+#define M8xx_MI_TWC 789 /* IMMU Tablewalk Control Register (TWC) */
+#define M8xx_MD_TWC 797 /* DMMU Tablewalk Control Register (TWC) */
+#define M8xx_MI_RPN 790 /* IMMU Real (physical) Page Number Register (RPN) */
+#define M8xx_MD_RPN 798 /* DMMU Real (physical) Page Number Register (RPN) */
+/* Tablewalk Assist Registers */
+#define M8xx_M_TWB 796 /* MMU Tablewalk Base Register (TWB) */
+/* Protection Registers */
+#define M8xx_M_CASID 793 /* MMU Current Address Space ID Register */
+#define M8xx_MI_AP 786 /* IMMU Access Protection Register */
+#define M8xx_MD_AP 794 /* DMMU Access Protection Register */
+/* Scratch Register */
+#define M8xx_M_TW 799 /* MMU Tablewalk Special Register */
+/* Debug Registers */
+#define M8xx_MI_CAM 816 /* IMMU CAM Entry Read Register */
+#define M8xx_MI_RAM0 817 /* IMMU RAM Entry Read Register 0 */
+#define M8xx_MI_RAM1 818 /* IMMU RAM Entry Read Register 1 */
+#define M8xx_MD_CAM 824 /* DMMU CAM Entry Read Register */
+#define M8xx_MD_RAM0 825 /* DMMU RAM Entry Read Register 0 */
+#define M8xx_MD_RAM1 826 /* DMMU RAM Entry Read Register 1 */
+
+#define M8xx_MI_CTR_GPM (1<<31)
+#define M8xx_MI_CTR_PPM (1<<30)
+#define M8xx_MI_CTR_CIDEF (1<<29)
+#define M8xx_MI_CTR_RSV4I (1<<27)
+#define M8xx_MI_CTR_PPCS (1<<25)
+#define M8xx_MI_CTR_ITLB_INDX(x) ((x)<<8) /* ITLB index */
+
+#define M8xx_MD_CTR_GPM (1<<31)
+#define M8xx_MD_CTR_PPM (1<<30)
+#define M8xx_MD_CTR_CIDEF (1<<29)
+#define M8xx_MD_CTR_WTDEF (1<<28)
+#define M8xx_MD_CTR_RSV4D (1<<27)
+#define M8xx_MD_CTR_TWAM (1<<26)
+#define M8xx_MD_CTR_PPCS (1<<25)
+#define M8xx_MD_CTR_DTLB_INDX(x) ((x)<<8) /* DTLB index */
+
+#define M8xx_MI_EPN_VALID (1<<9)
+
+#define M8xx_MD_EPN_VALID (1<<9)
+
+#define M8xx_MI_TWC_G (1<<4)
+#define M8xx_MI_TWC_PSS (0<<2)
+#define M8xx_MI_TWC_PS512 (1<<2)
+#define M8xx_MI_TWC_PS8 (3<<2)
+#define M8xx_MI_TWC_VALID (1)
+
+#define M8xx_MD_TWC_G (1<<4)
+#define M8xx_MD_TWC_PSS (0<<2)
+#define M8xx_MD_TWC_PS512 (1<<2)
+#define M8xx_MD_TWC_PS8 (3<<2)
+#define M8xx_MD_TWC_WT (1<<1)
+#define M8xx_MD_TWC_VALID (1)
+
+#define M8xx_MI_RPN_F (0xf<<4)
+#define M8xx_MI_RPN_16K (1<<3)
+#define M8xx_MI_RPN_SHARED (1<<2)
+#define M8xx_MI_RPN_CI (1<<1)
+#define M8xx_MI_RPN_VALID (1)
+
+#define M8xx_MD_RPN_CHANGE (1<<8)
+#define M8xx_MD_RPN_F (0xf<<4)
+#define M8xx_MD_RPN_16K (1<<3)
+#define M8xx_MD_RPN_SHARED (1<<2)
+#define M8xx_MD_RPN_CI (1<<1)
+#define M8xx_MD_RPN_VALID (1)
+
+#define M8xx_MI_AP_Kp (1)
+
+#define M8xx_MD_AP_Kp (1)
+
+#define M8xx_CACHE_CMD_SFWT (0x1<<24)
+#define M8xx_CACHE_CMD_ENABLE (0x2<<24)
+#define M8xx_CACHE_CMD_CFWT (0x3<<24)
+#define M8xx_CACHE_CMD_DISABLE (0x4<<24)
+#define M8xx_CACHE_CMD_STLES (0x5<<24)
+#define M8xx_CACHE_CMD_LLCB (0x6<<24)
+#define M8xx_CACHE_CMD_CLES (0x7<<24)
+#define M8xx_CACHE_CMD_UNLOCK (0x8<<24)
+#define M8xx_CACHE_CMD_UNLOCKALL (0xa<<24)
+#define M8xx_CACHE_CMD_INVALIDATE (0xc<<24)
+#define M8xx_CACHE_CMD_FLUSH (0xe<<24)
+
+/*
+*************************************************************************
+* REGISTER SUBBLOCKS *
+*************************************************************************
+*/
+
+/*
+ * Memory controller registers
+ */
+typedef struct m8xxMEMCRegisters_ {
+ rtems_unsigned32 _br;
+ rtems_unsigned32 _or; /* Used to be called 'or'; reserved ANSI C++ keyword */
+} m8xxMEMCRegisters_t;
+
+/*
+ * Serial Communications Controller registers
+ */
+typedef struct m8xxSCCRegisters_ {
+ rtems_unsigned32 gsmr_l;
+ rtems_unsigned32 gsmr_h;
+ rtems_unsigned16 psmr;
+ rtems_unsigned16 _pad0;
+ rtems_unsigned16 todr;
+ rtems_unsigned16 dsr;
+ rtems_unsigned16 scce;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned16 sccm;
+ rtems_unsigned8 _pad2;
+ rtems_unsigned8 sccs;
+ rtems_unsigned32 _pad3[2];
+} m8xxSCCRegisters_t;
+
+/*
+ * Serial Management Controller registers
+ */
+typedef struct m8xxSMCRegisters_ {
+ rtems_unsigned16 _pad0;
+ rtems_unsigned16 smcmr;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned8 smce;
+ rtems_unsigned8 _pad2;
+ rtems_unsigned16 _pad3;
+ rtems_unsigned8 smcm;
+ rtems_unsigned8 _pad4;
+ rtems_unsigned32 _pad5;
+} m8xxSMCRegisters_t;
+
+/*
+ * Fast Ethernet Controller registers (Only on MPC8xxT)
+ */
+typedef struct m8xxFECRegisters_ {
+ rtems_unsigned32 addr_low;
+ rtems_unsigned32 addr_high;
+ rtems_unsigned32 hash_table_high;
+ rtems_unsigned32 hash_table_low;
+ rtems_unsigned32 r_des_start;
+ rtems_unsigned32 x_des_start;
+ rtems_unsigned32 r_buf_size;
+ rtems_unsigned32 _pad0[9];
+ rtems_unsigned32 ecntrl;
+ rtems_unsigned32 ievent;
+ rtems_unsigned32 imask;
+ rtems_unsigned32 ivec;
+ rtems_unsigned32 r_des_active;
+ rtems_unsigned32 x_des_active;
+ rtems_unsigned32 _pad1[10];
+ rtems_unsigned32 mii_data;
+ rtems_unsigned32 mii_speed;
+ rtems_unsigned32 _pad2[17];
+ rtems_unsigned32 r_bound;
+ rtems_unsigned32 r_fstart;
+ rtems_unsigned32 _pad3[6];
+ rtems_unsigned32 x_fstart;
+ rtems_unsigned32 _pad4[17];
+ rtems_unsigned32 fun_code;
+ rtems_unsigned32 _pad5[3];
+ rtems_unsigned32 r_cntrl;
+ rtems_unsigned32 r_hash;
+ rtems_unsigned32 _pad6[14];
+ rtems_unsigned32 x_cntrl;
+ rtems_unsigned32 _pad7[30];
+
+} m8xxFECRegisters_t;
+
+#define M8xx_FEC_IEVENT_HBERR (1 << 31)
+#define M8xx_FEC_IEVENT_BABR (1 << 30)
+#define M8xx_FEC_IEVENT_BABT (1 << 29)
+#define M8xx_FEC_IEVENT_GRA (1 << 28)
+#define M8xx_FEC_IEVENT_TFINT (1 << 27)
+#define M8xx_FEC_IEVENT_TXB (1 << 26)
+#define M8xx_FEC_IEVENT_RFINT (1 << 25)
+#define M8xx_FEC_IEVENT_RXB (1 << 24)
+#define M8xx_FEC_IEVENT_MII (1 << 23)
+#define M8xx_FEC_IEVENT_EBERR (1 << 22)
+#define M8xx_FEC_IMASK_HBEEN (1 << 31)
+#define M8xx_FEC_IMASK_BREEN (1 << 30)
+#define M8xx_FEC_IMASK_BTEN (1 << 29)
+#define M8xx_FEC_IMASK_GRAEN (1 << 28)
+#define M8xx_FEC_IMASK_TFIEN (1 << 27)
+#define M8xx_FEC_IMASK_TBIEN (1 << 26)
+#define M8xx_FEC_IMASK_RFIEN (1 << 25)
+#define M8xx_FEC_IMASK_RBIEN (1 << 24)
+#define M8xx_FEC_IMASK_MIIEN (1 << 23)
+#define M8xx_FEC_IMASK_EBERREN (1 << 22)
+
+/*
+*************************************************************************
+* Miscellaneous Parameters *
+*************************************************************************
+*/
+typedef struct m8xxMiscParms_ {
+ rtems_unsigned16 rev_num;
+ rtems_unsigned16 _res1;
+ rtems_unsigned32 _res2;
+ rtems_unsigned32 _res3;
+} m8xxMiscParms_t;
+
+/*
+*************************************************************************
+* RISC Timers *
+*************************************************************************
+*/
+typedef struct m8xxTimerParms_ {
+ rtems_unsigned16 tm_base;
+ rtems_unsigned16 _tm_ptr;
+ rtems_unsigned16 _r_tmr;
+ rtems_unsigned16 _r_tmv;
+ rtems_unsigned32 tm_cmd;
+ rtems_unsigned32 tm_cnt;
+} m8xxTimerParms_t;
+
+/*
+ * RISC Controller Configuration Register (RCCR)
+ * All other bits in this register are reserved.
+ */
+#define M8xx_RCCR_TIME (1<<15) /* Enable timer */
+#define M8xx_RCCR_TIMEP(x) ((x)<<8) /* Timer period */
+#define M8xx_RCCR_DR1M (1<<7) /* IDMA Rqst 1 Mode */
+#define M8xx_RCCR_DR0M (1<<6) /* IDMA Rqst 0 Mode */
+#define M8xx_RCCR_DRQP(x) ((x)<<4) /* IDMA Rqst Priority */
+#define M8xx_RCCR_EIE (1<<3) /* External Interrupt Enable */
+#define M8xx_RCCR_SCD (1<<2) /* Scheduler Configuration */
+#define M8xx_RCCR_ERAM(x) (x) /* Enable RAM Microcode */
+
+/*
+ * Command register
+ * Set up this register before issuing a M8xx_CR_OP_SET_TIMER command.
+ */
+#define M8xx_TM_CMD_V (1<<31) /* Set to enable timer */
+#define M8xx_TM_CMD_R (1<<30) /* Set for automatic restart */
+#define M8xx_TM_CMD_PWM (1<<29) /* Set for PWM operation */
+#define M8xx_TM_CMD_TIMER(x) ((x)<<16) /* Select timer */
+#define M8xx_TM_CMD_PERIOD(x) (x) /* Timer period (16 bits) */
+
+/*
+*************************************************************************
+* DMA Controllers *
+*************************************************************************
+*/
+typedef struct m8xxIDMAparms_ {
+ rtems_unsigned16 ibase;
+ rtems_unsigned16 dcmr;
+ rtems_unsigned32 _sapr;
+ rtems_unsigned32 _dapr;
+ rtems_unsigned16 ibptr;
+ rtems_unsigned16 _write_sp;
+ rtems_unsigned32 _s_byte_c;
+ rtems_unsigned32 _d_byte_c;
+ rtems_unsigned32 _s_state;
+ rtems_unsigned32 _itemp[4];
+ rtems_unsigned32 _sr_mem;
+ rtems_unsigned16 _read_sp;
+ rtems_unsigned16 _res0;
+ rtems_unsigned16 _res1;
+ rtems_unsigned16 _res2;
+ rtems_unsigned32 _d_state;
+} m8xxIDMAparms_t;
+
+
+/*
+*************************************************************************
+* DSP *
+*************************************************************************
+*/
+typedef struct m8xxDSPparms_ {
+ rtems_unsigned32 fdbase;
+ rtems_unsigned32 _fd_ptr;
+ rtems_unsigned32 _dstate;
+ rtems_unsigned32 _pad0;
+ rtems_unsigned16 _dstatus;
+ rtems_unsigned16 _i;
+ rtems_unsigned16 _tap;
+ rtems_unsigned16 _cbase;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned16 _xptr;
+ rtems_unsigned16 _pad2;
+ rtems_unsigned16 _yptr;
+ rtems_unsigned16 _m;
+ rtems_unsigned16 _pad3;
+ rtems_unsigned16 _n;
+ rtems_unsigned16 _pad4;
+ rtems_unsigned16 _k;
+ rtems_unsigned16 _pad5;
+} m8xxDSPparms_t;
+
+/*
+*************************************************************************
+* Serial Communication Controllers *
+*************************************************************************
+*/
+typedef struct m8xxSCCparms_ {
+ rtems_unsigned16 rbase;
+ rtems_unsigned16 tbase;
+ rtems_unsigned8 rfcr;
+ rtems_unsigned8 tfcr;
+ rtems_unsigned16 mrblr;
+ rtems_unsigned32 _rstate;
+ rtems_unsigned32 _pad0;
+ rtems_unsigned16 _rbptr;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned32 _pad2;
+ rtems_unsigned32 _tstate;
+ rtems_unsigned32 _pad3;
+ rtems_unsigned16 _tbptr;
+ rtems_unsigned16 _pad4;
+ rtems_unsigned32 _pad5;
+ rtems_unsigned32 _rcrc;
+ rtems_unsigned32 _tcrc;
+ union {
+ struct {
+ rtems_unsigned32 _res0;
+ rtems_unsigned32 _res1;
+ rtems_unsigned16 max_idl;
+ rtems_unsigned16 _idlc;
+ rtems_unsigned16 brkcr;
+ rtems_unsigned16 parec;
+ rtems_unsigned16 frmec;
+ rtems_unsigned16 nosec;
+ rtems_unsigned16 brkec;
+ rtems_unsigned16 brkln;
+ rtems_unsigned16 uaddr[2];
+ rtems_unsigned16 _rtemp;
+ rtems_unsigned16 toseq;
+ rtems_unsigned16 character[8];
+ rtems_unsigned16 rccm;
+ rtems_unsigned16 rccr;
+ rtems_unsigned16 rlbc;
+ } uart;
+ } un;
+} m8xxSCCparms_t;
+
+typedef struct m8xxSCCENparms_ {
+ rtems_unsigned16 rbase;
+ rtems_unsigned16 tbase;
+ rtems_unsigned8 rfcr;
+ rtems_unsigned8 tfcr;
+ rtems_unsigned16 mrblr;
+ rtems_unsigned32 _rstate;
+ rtems_unsigned32 _pad0;
+ rtems_unsigned16 _rbptr;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned32 _pad2;
+ rtems_unsigned32 _tstate;
+ rtems_unsigned32 _pad3;
+ rtems_unsigned16 _tbptr;
+ rtems_unsigned16 _pad4;
+ rtems_unsigned32 _pad5;
+ rtems_unsigned32 _rcrc;
+ rtems_unsigned32 _tcrc;
+ union {
+ struct {
+ rtems_unsigned32 _res0;
+ rtems_unsigned32 _res1;
+ rtems_unsigned16 max_idl;
+ rtems_unsigned16 _idlc;
+ rtems_unsigned16 brkcr;
+ rtems_unsigned16 parec;
+ rtems_unsigned16 frmec;
+ rtems_unsigned16 nosec;
+ rtems_unsigned16 brkec;
+ rtems_unsigned16 brkln;
+ rtems_unsigned16 uaddr[2];
+ rtems_unsigned16 _rtemp;
+ rtems_unsigned16 toseq;
+ rtems_unsigned16 character[8];
+ rtems_unsigned16 rccm;
+ rtems_unsigned16 rccr;
+ rtems_unsigned16 rlbc;
+ } uart;
+ struct {
+ rtems_unsigned32 c_pres;
+ rtems_unsigned32 c_mask;
+ rtems_unsigned32 crcec;
+ rtems_unsigned32 alec;
+ rtems_unsigned32 disfc;
+ rtems_unsigned16 pads;
+ rtems_unsigned16 ret_lim;
+ rtems_unsigned16 _ret_cnt;
+ rtems_unsigned16 mflr;
+ rtems_unsigned16 minflr;
+ rtems_unsigned16 maxd1;
+ rtems_unsigned16 maxd2;
+ rtems_unsigned16 _maxd;
+ rtems_unsigned16 dma_cnt;
+ rtems_unsigned16 _max_b;
+ rtems_unsigned16 gaddr1;
+ rtems_unsigned16 gaddr2;
+ rtems_unsigned16 gaddr3;
+ rtems_unsigned16 gaddr4;
+ rtems_unsigned32 _tbuf0data0;
+ rtems_unsigned32 _tbuf0data1;
+ rtems_unsigned32 _tbuf0rba0;
+ rtems_unsigned32 _tbuf0crc;
+ rtems_unsigned16 _tbuf0bcnt;
+ rtems_unsigned16 paddr_h;
+ rtems_unsigned16 paddr_m;
+ rtems_unsigned16 paddr_l;
+ rtems_unsigned16 p_per;
+ rtems_unsigned16 _rfbd_ptr;
+ rtems_unsigned16 _tfbd_ptr;
+ rtems_unsigned16 _tlbd_ptr;
+ rtems_unsigned32 _tbuf1data0;
+ rtems_unsigned32 _tbuf1data1;
+ rtems_unsigned32 _tbuf1rba0;
+ rtems_unsigned32 _tbuf1crc;
+ rtems_unsigned16 _tbuf1bcnt;
+ rtems_unsigned16 _tx_len;
+ rtems_unsigned16 iaddr1;
+ rtems_unsigned16 iaddr2;
+ rtems_unsigned16 iaddr3;
+ rtems_unsigned16 iaddr4;
+ rtems_unsigned16 _boff_cnt;
+ rtems_unsigned16 taddr_l;
+ rtems_unsigned16 taddr_m;
+ rtems_unsigned16 taddr_h;
+ } ethernet;
+ } un;
+} m8xxSCCENparms_t;
+
+/*
+ * Receive and transmit function code register bits
+ * These apply to the function code registers of all devices, not just SCC.
+ */
+#define M8xx_RFCR_BO(x) ((x)<<3)
+#define M8xx_RFCR_MOT (2<<3)
+#define M8xx_RFCR_DMA_SPACE(x) (x)
+#define M8xx_TFCR_BO(x) ((x)<<3)
+#define M8xx_TFCR_MOT (2<<3)
+#define M8xx_TFCR_DMA_SPACE(x) (x)
+
+/*
+ * Event and mask registers (SCCE, SCCM)
+ */
+#define M8xx_SCCE_BRKE (1<<6)
+#define M8xx_SCCE_BRK (1<<4)
+#define M8xx_SCCE_BSY (1<<2)
+#define M8xx_SCCE_TX (1<<1)
+#define M8xx_SCCE_RX (1<<0)
+
+/*
+*************************************************************************
+* Serial Management Controllers *
+*************************************************************************
+*/
+typedef struct m8xxSMCparms_ {
+ rtems_unsigned16 rbase;
+ rtems_unsigned16 tbase;
+ rtems_unsigned8 rfcr;
+ rtems_unsigned8 tfcr;
+ rtems_unsigned16 mrblr;
+ rtems_unsigned32 _rstate;
+ rtems_unsigned32 _pad0;
+ rtems_unsigned16 _rbptr;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned32 _pad2;
+ rtems_unsigned32 _tstate;
+ rtems_unsigned32 _pad3;
+ rtems_unsigned16 _tbptr;
+ rtems_unsigned16 _pad4;
+ rtems_unsigned32 _pad5;
+ union {
+ struct {
+ rtems_unsigned16 max_idl;
+ rtems_unsigned16 _idlc;
+ rtems_unsigned16 brkln;
+ rtems_unsigned16 brkec;
+ rtems_unsigned16 brkcr;
+ rtems_unsigned16 _r_mask;
+ } uart;
+ struct {
+ rtems_unsigned16 _pad0[5];
+ } transparent;
+ } un;
+} m8xxSMCparms_t;
+
+/*
+ * Mode register
+ */
+#define M8xx_SMCMR_CLEN(x) ((x)<<11) /* Character length */
+#define M8xx_SMCMR_2STOP (1<<10) /* 2 stop bits */
+#define M8xx_SMCMR_PARITY (1<<9) /* Enable parity */
+#define M8xx_SMCMR_EVEN (1<<8) /* Even parity */
+#define M8xx_SMCMR_SM_GCI (0<<4) /* GCI Mode */
+#define M8xx_SMCMR_SM_UART (2<<4) /* UART Mode */
+#define M8xx_SMCMR_SM_TRANSPARENT (3<<4) /* Transparent Mode */
+#define M8xx_SMCMR_DM_LOOPBACK (1<<2) /* Local loopback mode */
+#define M8xx_SMCMR_DM_ECHO (2<<2) /* Echo mode */
+#define M8xx_SMCMR_TEN (1<<1) /* Enable transmitter */
+#define M8xx_SMCMR_REN (1<<0) /* Enable receiver */
+
+/*
+ * Event and mask registers (SMCE, SMCM)
+ */
+#define M8xx_SMCE_BRKE (1<<6)
+#define M8xx_SMCE_BRK (1<<4)
+#define M8xx_SMCE_BSY (1<<2)
+#define M8xx_SMCE_TX (1<<1)
+#define M8xx_SMCE_RX (1<<0)
+
+/*
+*************************************************************************
+* Serial Peripheral Interface *
+*************************************************************************
+*/
+typedef struct m8xxSPIparms_ {
+ rtems_unsigned16 rbase;
+ rtems_unsigned16 tbase;
+ rtems_unsigned8 rfcr;
+ rtems_unsigned8 tfcr;
+ rtems_unsigned16 mrblr;
+ rtems_unsigned32 _rstate;
+ rtems_unsigned32 _pad0;
+ rtems_unsigned16 _rbptr;
+ rtems_unsigned16 _pad1;
+ rtems_unsigned32 _pad2;
+ rtems_unsigned32 _tstate;
+ rtems_unsigned32 _pad3;
+ rtems_unsigned16 _tbptr;
+ rtems_unsigned16 _pad4;
+ rtems_unsigned32 _pad5;
+} m8xxSPIparms_t;
+
+/*
+ * Mode register (SPMODE)
+ */
+#define M8xx_SPMODE_LOOP (1<<14) /* Local loopback mode */
+#define M8xx_SPMODE_CI (1<<13) /* Clock invert */
+#define M8xx_SPMODE_CP (1<<12) /* Clock phase */
+#define M8xx_SPMODE_DIV16 (1<<11) /* Divide BRGCLK by 16 */
+#define M8xx_SPMODE_REV (1<<10) /* Reverse data */
+#define M8xx_SPMODE_MASTER (1<<9) /* SPI is master */
+#define M8xx_SPMODE_EN (1<<8) /* Enable SPI */
+#define M8xx_SPMODE_CLEN(x) ((x)<<4) /* Character length */
+#define M8xx_SPMODE_PM(x) (x) /* Prescaler modulus */
+
+/*
+ * Mode register (SPCOM)
+ */
+#define M8xx_SPCOM_STR (1<<7) /* Start transmit */
+
+/*
+ * Event and mask registers (SPIE, SPIM)
+ */
+#define M8xx_SPIE_MME (1<<5) /* Multi-master error */
+#define M8xx_SPIE_TXE (1<<4) /* Tx error */
+#define M8xx_SPIE_BSY (1<<2) /* Busy condition*/
+#define M8xx_SPIE_TXB (1<<1) /* Tx buffer */
+#define M8xx_SPIE_RXB (1<<0) /* Rx buffer */
+
+/*
+*************************************************************************
+* SDMA (SCC, SMC, SPI) Buffer Descriptors *
+*************************************************************************
+*/
+typedef struct m8xxBufferDescriptor_ {
+ rtems_unsigned16 status;
+ rtems_unsigned16 length;
+ volatile void *buffer;
+} m8xxBufferDescriptor_t;
+
+/*
+ * Bits in receive buffer descriptor status word
+ */
+#define M8xx_BD_EMPTY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M8xx_BD_WRAP (1<<13) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M8xx_BD_INTERRUPT (1<<12) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M8xx_BD_LAST (1<<11) /* Ethernet, SPI */
+#define M8xx_BD_CONTROL_CHAR (1<<11) /* SCC UART */
+#define M8xx_BD_FIRST_IN_FRAME (1<<10) /* Ethernet */
+#define M8xx_BD_ADDRESS (1<<10) /* SCC UART */
+#define M8xx_BD_CONTINUOUS (1<<9) /* SCC UART, SMC UART, SPI */
+#define M8xx_BD_MISS (1<<8) /* Ethernet */
+#define M8xx_BD_IDLE (1<<8) /* SCC UART, SMC UART */
+#define M8xx_BD_ADDRSS_MATCH (1<<7) /* SCC UART */
+#define M8xx_BD_LONG (1<<5) /* Ethernet */
+#define M8xx_BD_BREAK (1<<5) /* SCC UART, SMC UART */
+#define M8xx_BD_NONALIGNED (1<<4) /* Ethernet */
+#define M8xx_BD_FRAMING_ERROR (1<<4) /* SCC UART, SMC UART */
+#define M8xx_BD_SHORT (1<<3) /* Ethernet */
+#define M8xx_BD_PARITY_ERROR (1<<3) /* SCC UART, SMC UART */
+#define M8xx_BD_CRC_ERROR (1<<2) /* Ethernet */
+#define M8xx_BD_OVERRUN (1<<1) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M8xx_BD_COLLISION (1<<0) /* Ethernet */
+#define M8xx_BD_CARRIER_LOST (1<<0) /* SCC UART, SMC UART */
+#define M8xx_BD_MASTER_ERROR (1<<0) /* SPI */
+
+/*
+ * Bits in transmit buffer descriptor status word
+ * Many bits have the same meaning as those in receiver buffer descriptors.
+ */
+#define M8xx_BD_READY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M8xx_BD_PAD (1<<14) /* Ethernet */
+#define M8xx_BD_CTS_REPORT (1<<11) /* SCC UART */
+#define M8xx_BD_TX_CRC (1<<10) /* Ethernet */
+#define M8xx_BD_DEFER (1<<9) /* Ethernet */
+#define M8xx_BD_HEARTBEAT (1<<8) /* Ethernet */
+#define M8xx_BD_PREAMBLE (1<<8) /* SCC UART, SMC UART */
+#define M8xx_BD_LATE_COLLISION (1<<7) /* Ethernet */
+#define M8xx_BD_NO_STOP_BIT (1<<7) /* SCC UART */
+#define M8xx_BD_RETRY_LIMIT (1<<6) /* Ethernet */
+#define M8xx_BD_RETRY_COUNT(x) (((x)&0x3C)>>2) /* Ethernet */
+#define M8xx_BD_UNDERRUN (1<<1) /* Ethernet, SPI */
+#define M8xx_BD_CARRIER_LOST (1<<0) /* Ethernet */
+#define M8xx_BD_CTS_LOST (1<<0) /* SCC UART */
+
+/*
+*************************************************************************
+* IDMA Buffer Descriptors *
+*************************************************************************
+*/
+typedef struct m8xxIDMABufferDescriptor_ {
+ rtems_unsigned16 status;
+ rtems_unsigned8 dfcr;
+ rtems_unsigned8 sfcr;
+ rtems_unsigned32 length;
+ void *source;
+ void *destination;
+} m8xxIDMABufferDescriptor_t;
+
+/*
+*************************************************************************
+* RISC Communication Processor Module Command Register (CR) *
+*************************************************************************
+*/
+#define M8xx_CR_RST (1<<15) /* Reset communication processor */
+#define M8xx_CR_OP_INIT_RX_TX (0<<8) /* SCC, SMC UART, SMC GCI, SPI */
+#define M8xx_CR_OP_INIT_RX (1<<8) /* SCC, SMC UART, SPI */
+#define M8xx_CR_OP_INIT_TX (2<<8) /* SCC, SMC UART, SPI */
+#define M8xx_CR_OP_INIT_HUNT (3<<8) /* SCC, SMC UART */
+#define M8xx_CR_OP_STOP_TX (4<<8) /* SCC, SMC UART */
+#define M8xx_CR_OP_GR_STOP_TX (5<<8) /* SCC */
+#define M8xx_CR_OP_INIT_IDMA (5<<8) /* IDMA */
+#define M8xx_CR_OP_RESTART_TX (6<<8) /* SCC, SMC UART */
+#define M8xx_CR_OP_CLOSE_RX_BD (7<<8) /* SCC, SMC UART, SPI */
+#define M8xx_CR_OP_SET_GRP_ADDR (8<<8) /* SCC */
+#define M8xx_CR_OP_SET_TIMER (8<<8) /* Timer */
+#define M8xx_CR_OP_GCI_TIMEOUT (9<<8) /* SMC GCI */
+#define M8xx_CR_OP_RESERT_BCS (10<<8) /* SCC */
+#define M8xx_CR_OP_GCI_ABORT (10<<8) /* SMC GCI */
+#define M8xx_CR_OP_STOP_IDMA (11<<8) /* IDMA */
+#define M8xx_CR_OP_START_DSP (12<<8) /* DSP */
+#define M8xx_CR_OP_INIT_DSP (13<<8) /* DSP */
+
+#define M8xx_CR_CHAN_SCC1 (0<<4) /* Channel selection */
+#define M8xx_CR_CHAN_I2C (1<<4)
+#define M8xx_CR_CHAN_IDMA1 (1<<4)
+#define M8xx_CR_CHAN_SCC2 (4<<4)
+#define M8xx_CR_CHAN_SPI (5<<4)
+#define M8xx_CR_CHAN_IDMA2 (5<<4)
+#define M8xx_CR_CHAN_TIMER (5<<4)
+#define M8xx_CR_CHAN_SCC3 (8<<4)
+#define M8xx_CR_CHAN_SMC1 (9<<4)
+#define M8xx_CR_CHAN_DSP1 (9<<4)
+#define M8xx_CR_CHAN_SCC4 (12<<4)
+#define M8xx_CR_CHAN_SMC2 (13<<4)
+#define M8xx_CR_CHAN_DSP2 (13<<4)
+#define M8xx_CR_FLG (1<<0) /* Command flag */
+
+/*
+*************************************************************************
+* System Protection Control Register (SYPCR) *
+*************************************************************************
+*/
+#define M8xx_SYPCR_SWTC(x) ((x)<<16) /* Software watchdog timer count */
+#define M8xx_SYPCR_BMT(x) ((x)<<8) /* Bus monitor timing */
+#define M8xx_SYPCR_BME (1<<7) /* Bus monitor enable */
+#define M8xx_SYPCR_SWF (1<<3) /* Software watchdog freeze */
+#define M8xx_SYPCR_SWE (1<<2) /* Software watchdog enable */
+#define M8xx_SYPCR_SWRI (1<<1) /* Watchdog reset/interrupt sel. */
+#define M8xx_SYPCR_SWP (1<<0) /* Software watchdog prescale */
+
+/*
+*************************************************************************
+* Memory Control Registers *
+*************************************************************************
+*/
+#define M8xx_UPM_AMX_8col (0<<20) /* 8 column DRAM */
+#define M8xx_UPM_AMX_9col (1<<20) /* 9 column DRAM */
+#define M8xx_UPM_AMX_10col (2<<20) /* 10 column DRAM */
+#define M8xx_UPM_AMX_11col (3<<20) /* 11 column DRAM */
+#define M8xx_UPM_AMX_12col (4<<20) /* 12 column DRAM */
+#define M8xx_UPM_AMX_13col (5<<20) /* 13 column DRAM */
+#define M8xx_MSR_PER(x) (0x100<<(7-x)) /* Perity error bank (x) */
+#define M8xx_MSR_WPER (1<<7) /* Write protection error */
+#define M8xx_MPTPR_PTP(x) ((x)<<8) /* Periodic timer prescaler */
+#define M8xx_BR_BA(x) ((x)&0xffff8000) /* Base address */
+#define M8xx_BR_AT(x) ((x)<<12) /* Address type */
+#define M8xx_BR_PS8 (1<<10) /* 8 bit port */
+#define M8xx_BR_PS16 (2<<10) /* 16 bit port */
+#define M8xx_BR_PS32 (0<<10) /* 32 bit port */
+#define M8xx_BR_PARE (1<<9) /* Parity checking enable */
+#define M8xx_BR_WP (1<<8) /* Write protect */
+#define M8xx_BR_MS_GPCM (0<<6) /* GPCM */
+#define M8xx_BR_MS_UPMA (2<<6) /* UPM A */
+#define M8xx_BR_MS_UPMB (3<<6) /* UPM B */
+#define M8xx_MEMC_BR_V (1<<0) /* Base/Option register are valid */
+
+#define M8xx_MEMC_OR_32K 0xffff8000 /* Address range */
+#define M8xx_MEMC_OR_64K 0xffff0000
+#define M8xx_MEMC_OR_128K 0xfffe0000
+#define M8xx_MEMC_OR_256K 0xfffc0000
+#define M8xx_MEMC_OR_512K 0xfff80000
+#define M8xx_MEMC_OR_1M 0xfff00000
+#define M8xx_MEMC_OR_2M 0xffe00000
+#define M8xx_MEMC_OR_4M 0xffc00000
+#define M8xx_MEMC_OR_8M 0xff800000
+#define M8xx_MEMC_OR_16M 0xff000000
+#define M8xx_MEMC_OR_32M 0xfe000000
+#define M8xx_MEMC_OR_64M 0xfc000000
+#define M8xx_MEMC_OR_128 0xf8000000
+#define M8xx_MEMC_OR_256M 0xf0000000
+#define M8xx_MEMC_OR_512M 0xe0000000
+#define M8xx_MEMC_OR_1G 0xc0000000
+#define M8xx_MEMC_OR_2G 0x80000000
+#define M8xx_MEMC_OR_4G 0x00000000
+#define M8xx_MEMC_OR_ATM(x) ((x)<<12) /* Address type mask */
+#define M8xx_MEMC_OR_CSNT (1<<11) /* Chip select is negated early */
+#define M8xx_MEMC_OR_SAM (1<<11) /* Address lines are multiplexed */
+#define M8xx_MEMC_OR_ACS_NORM (0<<9) /* *CS asserted with addr lines */
+#define M8xx_MEMC_OR_ACS_QRTR (2<<9) /* *CS asserted 1/4 after addr */
+#define M8xx_MEMC_OR_ACS_HALF (3<<9) /* *CS asserted 1/2 after addr */
+#define M8xx_MEMC_OR_BI (1<<8) /* Burst inhibit */
+#define M8xx_MEMC_OR_SCY(x) ((x)<<4) /* Cycle length in clocks */
+#define M8xx_MEMC_OR_SETA (1<<3) /* *TA generated externally */
+#define M8xx_MEMC_OR_TRLX (1<<2) /* Relaxed timing in GPCM */
+#define M8xx_MEMC_OR_EHTR (1<<1) /* Extended hold time on reads */
+
+/*
+*************************************************************************
+* UPM Registers (MxMR) *
+*************************************************************************
+*/
+#define M8xx_MEMC_MMR_PTP(x) ((x)<<24) /* Periodic timer period */
+#define M8xx_MEMC_MMR_PTE (1<<23) /* Periodic timer enable */
+#define M8xx_MEMC_MMR_DSP(x) ((x)<<17) /* Disable timer period */
+#define M8xx_MEMC_MMR_G0CL(x) ((x)<<13) /* General line 0 control */
+#define M8xx_MEMC_MMR_UPWAIT (1<<12) /* GPL_x4 is UPWAITx */
+#define M8xx_MEMC_MMR_RLF(x) ((x)<<8) /* Read loop field */
+#define M8xx_MEMC_MMR_WLF(x) ((x)<<4) /* Write loop field */
+#define M8xx_MEMC_MMR_TLF(x) ((x)<<0) /* Timer loop field */
+/*
+*************************************************************************
+* Memory Command Register (MCR) *
+*************************************************************************
+*/
+#define M8xx_MEMC_MCR_WRITE (0<<30) /* WRITE command */
+#define M8xx_MEMC_MCR_READ (1<<30) /* READ command */
+#define M8xx_MEMC_MCR_RUN (2<<30) /* RUN command */
+#define M8xx_MEMC_MCR_UPMA (0<<23) /* Cmd is for UPMA */
+#define M8xx_MEMC_MCR_UPMB (1<<23) /* Cmd is for UPMB */
+#define M8xx_MEMC_MCR_MB(x) ((x)<<13) /* Memory bank when RUN cmd */
+#define M8xx_MEMC_MCR_MCLF(x) ((x)<<8) /* Memory command loop field */
+#define M8xx_MEMC_MCR_MAD(x) (x) /* Machine address */
+
+
+
+/*
+*************************************************************************
+* SI Mode Register (SIMODE) *
+*************************************************************************
+*/
+#define M8xx_SI_SMC2_BITS 0xFFFF0000 /* All SMC2 bits */
+#define M8xx_SI_SMC2_TDM (1<<31) /* Multiplexed SMC2 */
+#define M8xx_SI_SMC2_BRG1 (0<<28) /* SMC2 clock souce */
+#define M8xx_SI_SMC2_BRG2 (1<<28)
+#define M8xx_SI_SMC2_BRG3 (2<<28)
+#define M8xx_SI_SMC2_BRG4 (3<<28)
+#define M8xx_SI_SMC2_CLK5 (0<<28)
+#define M8xx_SI_SMC2_CLK6 (1<<28)
+#define M8xx_SI_SMC2_CLK7 (2<<28)
+#define M8xx_SI_SMC2_CLK8 (3<<28)
+#define M8xx_SI_SMC1_BITS 0x0000FFFF /* All SMC1 bits */
+#define M8xx_SI_SMC1_TDM (1<<15) /* Multiplexed SMC1 */
+#define M8xx_SI_SMC1_BRG1 (0<<12) /* SMC1 clock souce */
+#define M8xx_SI_SMC1_BRG2 (1<<12)
+#define M8xx_SI_SMC1_BRG3 (2<<12)
+#define M8xx_SI_SMC1_BRG4 (3<<12)
+#define M8xx_SI_SMC1_CLK1 (0<<12)
+#define M8xx_SI_SMC1_CLK2 (1<<12)
+#define M8xx_SI_SMC1_CLK3 (2<<12)
+#define M8xx_SI_SMC1_CLK4 (3<<12)
+
+/*
+*************************************************************************
+* SDMA Configuration Register (SDCR) *
+*************************************************************************
+*/
+#define M8xx_SDCR_FREEZE (2<<13) /* Freeze on next bus cycle */
+#define M8xx_SDCR_RAID_5 (1<<0) /* Normal arbitration ID */
+
+/*
+*************************************************************************
+* SDMA Status Register (SDSR) *
+*************************************************************************
+*/
+#define M8xx_SDSR_SBER (1<<7) /* SDMA Channel bus error */
+#define M8xx_SDSR_DSP2 (1<<1) /* DSP Chain 2 interrupt */
+#define M8xx_SDSR_DSP1 (1<<0) /* DSP Chain 1 interrupt */
+
+/*
+*************************************************************************
+* Baud (sic) Rate Generators *
+*************************************************************************
+*/
+#define M8xx_BRG_RST (1<<17) /* Reset generator */
+#define M8xx_BRG_EN (1<<16) /* Enable generator */
+#define M8xx_BRG_EXTC_BRGCLK (0<<14) /* Source is BRGCLK */
+#define M8xx_BRG_EXTC_CLK2 (1<<14) /* Source is CLK2 pin */
+#define M8xx_BRG_EXTC_CLK6 (2<<14) /* Source is CLK6 pin */
+#define M8xx_BRG_ATB (1<<13) /* Autobaud */
+#define M8xx_BRG_115200 (21<<1) /* Assume 40 MHz clock */
+#define M8xx_BRG_57600 (32<<1)
+#define M8xx_BRG_38400 (64<<1)
+#define M8xx_BRG_19200 (129<<1)
+#define M8xx_BRG_9600 (259<<1)
+#define M8xx_BRG_4800 (520<<1)
+#define M8xx_BRG_2400 (1040<<1)
+#define M8xx_BRG_1200 (2082<<1)
+#define M8xx_BRG_600 ((259<<1) | 1)
+#define M8xx_BRG_300 ((520<<1) | 1)
+#define M8xx_BRG_150 ((1040<<1) | 1)
+#define M8xx_BRG_75 ((2080<<1) | 1)
+
+#define M8xx_TGCR_CAS4 (1<<15) /* Cascade timers 3 and 4 */
+#define M8xx_TGCR_CAS2 (1<<7) /* Cascade timers 1 and 2 */
+#define M8xx_TGCR_FRZ1 (1<<2) /* Halt timer if FREEZE asserted */
+#define M8xx_TGCR_FRZ2 (1<<6) /* Halt timer if FREEZE asserted */
+#define M8xx_TGCR_FRZ3 (1<<10) /* Halt timer if FREEZE asserted */
+#define M8xx_TGCR_FRZ4 (1<<14) /* Halt timer if FREEZE asserted */
+#define M8xx_TGCR_STP1 (1<<1) /* Stop timer */
+#define M8xx_TGCR_STP2 (1<<5) /* Stop timer */
+#define M8xx_TGCR_STP3 (1<<9) /* Stop timer */
+#define M8xx_TGCR_STP4 (1<<13) /* Stop timer */
+#define M8xx_TGCR_RST1 (1<<0) /* Enable timer */
+#define M8xx_TGCR_RST2 (1<<4) /* Enable timer */
+#define M8xx_TGCR_RST3 (1<<8) /* Enable timer */
+#define M8xx_TGCR_RST4 (1<<12) /* Enable timer */
+#define M8xx_TGCR_GM1 (1<<3) /* Gate Mode 1 for TMR1 or TMR2 */
+#define M8xx_TGCR_GM2 (1<<11) /* Gate Mode 2 for TMR3 or TMR4 */
+
+#define M8xx_TMR_PS(x) ((x)<<8) /* Timer prescaler */
+#define M8xx_TMR_CE_RISE (1<<6) /* Capture on rising edge */
+#define M8xx_TMR_CE_FALL (2<<6) /* Capture on falling edge */
+#define M8xx_TMR_CE_ANY (3<<6) /* Capture on any edge */
+#define M8xx_TMR_OM_TOGGLE (1<<5) /* Toggle TOUTx pin */
+#define M8xx_TMR_ORI (1<<4) /* Interrupt on reaching reference */
+#define M8xx_TMR_RESTART (1<<3) /* Restart timer after reference */
+#define M8xx_TMR_ICLK_INT (1<<1) /* Internal clock is timer source */
+#define M8xx_TMR_ICLK_INT16 (2<<1) /* Internal clock/16 is tmr src */
+#define M8xx_TMR_ICLK_TIN (3<<1) /* TIN pin is timer source */
+#define M8xx_TMR_TGATE (1<<0) /* TGATE controls timer */
+
+#define M8xx_PISCR_PIRQ(x) (1<<(15-x)) /* PIT interrupt level */
+#define M8xx_PISCR_PS (1<<7) /* PIT Interrupt state */
+#define M8xx_PISCR_PIE (1<<2) /* PIT interrupt enable */
+#define M8xx_PISCR_PITF (1<<1) /* Stop timer when freeze asserted */
+#define M8xx_PISCR_PTE (1<<0) /* PIT enable */
+
+#define M8xx_TBSCR_TBIRQ(x) (1<<(15-x)) /* TB interrupt level */
+#define M8xx_TBSCR_REFA (1<<7) /* TB matches TBREFF0 */
+#define M8xx_TBSCR_REFB (1<<6) /* TB matches TBREFF1 */
+#define M8xx_TBSCR_REFAE (1<<3) /* Enable ints for REFA */
+#define M8xx_TBSCR_REFBE (1<<2) /* Enable ints for REFB */
+#define M8xx_TBSCR_TBF (1<<1) /* TB stops on FREEZE */
+#define M8xx_TBSCR_TBE (1<<0) /* enable TB and decrementer */
+
+#define M8xx_SIMASK_IRM0 (1<<31)
+#define M8xx_SIMASK_LVM0 (1<<30)
+#define M8xx_SIMASK_IRM1 (1<<29)
+#define M8xx_SIMASK_LVM1 (1<<28)
+#define M8xx_SIMASK_IRM2 (1<<27)
+#define M8xx_SIMASK_LVM2 (1<<26)
+#define M8xx_SIMASK_IRM3 (1<<25)
+#define M8xx_SIMASK_LVM3 (1<<24)
+#define M8xx_SIMASK_IRM4 (1<<23)
+#define M8xx_SIMASK_LVM4 (1<<22)
+#define M8xx_SIMASK_IRM5 (1<<21)
+#define M8xx_SIMASK_LVM5 (1<<20)
+#define M8xx_SIMASK_IRM6 (1<<19)
+#define M8xx_SIMASK_LVM6 (1<<18)
+#define M8xx_SIMASK_IRM7 (1<<17)
+#define M8xx_SIMASK_LVM7 (1<<16)
+
+#define M8xx_SIUMCR_EARB (1<<31)
+#define M8xx_SIUMCR_EARP0 (0<<28)
+#define M8xx_SIUMCR_EARP1 (1<<28)
+#define M8xx_SIUMCR_EARP2 (2<<28)
+#define M8xx_SIUMCR_EARP3 (3<<28)
+#define M8xx_SIUMCR_EARP4 (4<<28)
+#define M8xx_SIUMCR_EARP5 (5<<28)
+#define M8xx_SIUMCR_EARP6 (6<<28)
+#define M8xx_SIUMCR_EARP7 (7<<28)
+#define M8xx_SIUMCR_DSHW (1<<23)
+#define M8xx_SIUMCR_DBGC0 (0<<21)
+#define M8xx_SIUMCR_DBGC1 (1<<21)
+#define M8xx_SIUMCR_DBGC2 (2<<21)
+#define M8xx_SIUMCR_DBGC3 (3<<21)
+#define M8xx_SIUMCR_DBPC0 (0<<19)
+#define M8xx_SIUMCR_DBPC1 (1<<19)
+#define M8xx_SIUMCR_DBPC2 (2<<19)
+#define M8xx_SIUMCR_DBPC3 (3<<19)
+#define M8xx_SIUMCR_FRC (1<<17)
+#define M8xx_SIUMCR_DLK (1<<16)
+#define M8xx_SIUMCR_PNCS (1<<15)
+#define M8xx_SIUMCR_OPAR (1<<14)
+#define M8xx_SIUMCR_DPC (1<<13)
+#define M8xx_SIUMCR_MPRE (1<<12)
+#define M8xx_SIUMCR_MLRC0 (0<<10)
+#define M8xx_SIUMCR_MLRC1 (1<<10)
+#define M8xx_SIUMCR_MLRC2 (2<<10)
+#define M8xx_SIUMCR_MLRC3 (3<<10)
+#define M8xx_SIUMCR_AEME (1<<9)
+#define M8xx_SIUMCR_SEME (1<<8)
+#define M8xx_SIUMCR_BSC (1<<7)
+#define M8xx_SIUMCR_GB5E (1<<6)
+#define M8xx_SIUMCR_B2DD (1<<5)
+#define M8xx_SIUMCR_B3DD (1<<4)
+
+/*
+ * Value to write to a key register to unlock the corresponding SIU register
+ */
+#define M8xx_UNLOCK_KEY 0x55CCAA33
+
+/*
+*************************************************************************
+* MPC8xx INTERNAL MEMORY MAP REGISTERS (IMMR provides base address) *
+*************************************************************************
+*/
+typedef struct m8xx_ {
+
+ /*
+ * SIU Block
+ */
+ rtems_unsigned32 siumcr;
+ rtems_unsigned32 sypcr;
+#if defined(mpc860)
+ rtems_unsigned32 swt;
+#elif defined(mpc821)
+ rtems_unsigned32 _pad70;
+#endif
+ rtems_unsigned16 _pad0;
+ rtems_unsigned16 swsr;
+ rtems_unsigned32 sipend;
+ rtems_unsigned32 simask;
+ rtems_unsigned32 siel;
+ rtems_unsigned32 sivec;
+ rtems_unsigned32 tesr;
+ rtems_unsigned32 _pad1[3];
+ rtems_unsigned32 sdcr;
+ rtems_unsigned8 _pad2[0x80-0x34];
+
+ /*
+ * PCMCIA Block
+ */
+ rtems_unsigned32 pbr0;
+ rtems_unsigned32 por0;
+ rtems_unsigned32 pbr1;
+ rtems_unsigned32 por1;
+ rtems_unsigned32 pbr2;
+ rtems_unsigned32 por2;
+ rtems_unsigned32 pbr3;
+ rtems_unsigned32 por3;
+ rtems_unsigned32 pbr4;
+ rtems_unsigned32 por4;
+ rtems_unsigned32 pbr5;
+ rtems_unsigned32 por5;
+ rtems_unsigned32 pbr6;
+ rtems_unsigned32 por6;
+ rtems_unsigned32 pbr7;
+ rtems_unsigned32 por7;
+ rtems_unsigned8 _pad3[0xe0-0xc0];
+ rtems_unsigned32 pgcra;
+ rtems_unsigned32 pgcrb;
+ rtems_unsigned32 pscr;
+ rtems_unsigned32 _pad4;
+ rtems_unsigned32 pipr;
+ rtems_unsigned32 _pad5;
+ rtems_unsigned32 per;
+ rtems_unsigned32 _pad6;
+
+ /*
+ * MEMC Block
+ */
+ m8xxMEMCRegisters_t memc[8];
+ rtems_unsigned8 _pad7[0x164-0x140];
+ rtems_unsigned32 mar;
+ rtems_unsigned32 mcr;
+ rtems_unsigned32 _pad8;
+ rtems_unsigned32 mamr;
+ rtems_unsigned32 mbmr;
+ rtems_unsigned16 mstat;
+ rtems_unsigned16 mptpr;
+ rtems_unsigned32 mdr;
+ rtems_unsigned8 _pad9[0x200-0x180];
+
+ /*
+ * System integration timers
+ */
+ rtems_unsigned16 tbscr;
+ rtems_unsigned16 _pad10;
+ rtems_unsigned32 tbreff0;
+ rtems_unsigned32 tbreff1;
+ rtems_unsigned8 _pad11[0x220-0x20c];
+ rtems_unsigned16 rtcsc;
+ rtems_unsigned16 _pad12;
+ rtems_unsigned32 rtc;
+ rtems_unsigned32 rtsec;
+ rtems_unsigned32 rtcal;
+ rtems_unsigned32 _pad13[4];
+ rtems_unsigned16 piscr;
+ rtems_unsigned16 _pad14;
+ rtems_unsigned16 pitc;
+ rtems_unsigned16 _pad_14_1;
+ rtems_unsigned16 pitr;
+ rtems_unsigned16 _pad_14_2;
+ rtems_unsigned8 _pad15[0x280-0x24c];
+
+
+ /*
+ * Clocks and Reset
+ */
+ rtems_unsigned32 sccr;
+ rtems_unsigned32 plprcr;
+ rtems_unsigned32 rsr;
+ rtems_unsigned8 _pad16[0x300-0x28c];
+
+
+ /*
+ * System integration timers keys
+ */
+ rtems_unsigned32 tbscrk;
+ rtems_unsigned32 tbreff0k;
+ rtems_unsigned32 tbreff1k;
+ rtems_unsigned32 tbk;
+ rtems_unsigned32 _pad17[4];
+ rtems_unsigned32 rtcsk;
+ rtems_unsigned32 rtck;
+ rtems_unsigned32 rtseck;
+ rtems_unsigned32 rtcalk;
+ rtems_unsigned32 _pad18[4];
+ rtems_unsigned32 piscrk;
+ rtems_unsigned32 pitck;
+ rtems_unsigned8 _pad19[0x380-0x348];
+
+ /*
+ * Clocks and Reset Keys
+ */
+ rtems_unsigned32 sccrk;
+ rtems_unsigned32 plprck;
+ rtems_unsigned32 rsrk;
+ rtems_unsigned8 _pad20[0x400-0x38c];
+ rtems_unsigned8 _pad21[0x800-0x400];
+ rtems_unsigned8 _pad22[0x860-0x800];
+
+
+ /*
+ * I2C
+ */
+ rtems_unsigned8 i2mod;
+ rtems_unsigned8 _pad23[3];
+ rtems_unsigned8 i2add;
+ rtems_unsigned8 _pad24[3];
+ rtems_unsigned8 i2brg;
+ rtems_unsigned8 _pad25[3];
+ rtems_unsigned8 i2com;
+ rtems_unsigned8 _pad26[3];
+ rtems_unsigned8 i2cer;
+ rtems_unsigned8 _pad27[3];
+ rtems_unsigned8 i2cmr;
+ rtems_unsigned8 _pad28[0x900-0x875];
+
+ /*
+ * DMA Block
+ */
+ rtems_unsigned32 _pad29;
+ rtems_unsigned32 sdar;
+ rtems_unsigned8 sdsr;
+ rtems_unsigned8 _pad30[3];
+ rtems_unsigned8 sdmr;
+ rtems_unsigned8 _pad31[3];
+ rtems_unsigned8 idsr1;
+ rtems_unsigned8 _pad32[3];
+ rtems_unsigned8 idmr1;
+ rtems_unsigned8 _pad33[3];
+ rtems_unsigned8 idsr2;
+ rtems_unsigned8 _pad34[3];
+ rtems_unsigned8 idmr2;
+ rtems_unsigned8 _pad35[0x930-0x91d];
+
+ /*
+ * CPM Interrupt Control Block
+ */
+ rtems_unsigned16 civr;
+ rtems_unsigned8 _pad36[14];
+ rtems_unsigned32 cicr;
+ rtems_unsigned32 cipr;
+ rtems_unsigned32 cimr;
+ rtems_unsigned32 cisr;
+
+ /*
+ * I/O Port Block
+ */
+ rtems_unsigned16 padir;
+ rtems_unsigned16 papar;
+ rtems_unsigned16 paodr;
+ rtems_unsigned16 padat;
+ rtems_unsigned8 _pad37[8];
+ rtems_unsigned16 pcdir;
+ rtems_unsigned16 pcpar;
+ rtems_unsigned16 pcso;
+ rtems_unsigned16 pcdat;
+ rtems_unsigned16 pcint;
+ rtems_unsigned8 _pad39[6];
+ rtems_unsigned16 pddir;
+ rtems_unsigned16 pdpar;
+ rtems_unsigned16 _pad40;
+ rtems_unsigned16 pddat;
+ rtems_unsigned8 _pad41[8];
+
+ /*
+ * CPM Timers Block
+ */
+ rtems_unsigned16 tgcr;
+ rtems_unsigned8 _pad42[14];
+ rtems_unsigned16 tmr1;
+ rtems_unsigned16 tmr2;
+ rtems_unsigned16 trr1;
+ rtems_unsigned16 trr2;
+ rtems_unsigned16 tcr1;
+ rtems_unsigned16 tcr2;
+ rtems_unsigned16 tcn1;
+ rtems_unsigned16 tcn2;
+ rtems_unsigned16 tmr3;
+ rtems_unsigned16 tmr4;
+ rtems_unsigned16 trr3;
+ rtems_unsigned16 trr4;
+ rtems_unsigned16 tcr3;
+ rtems_unsigned16 tcr4;
+ rtems_unsigned16 tcn3;
+ rtems_unsigned16 tcn4;
+ rtems_unsigned16 ter1;
+ rtems_unsigned16 ter2;
+ rtems_unsigned16 ter3;
+ rtems_unsigned16 ter4;
+ rtems_unsigned8 _pad43[8];
+
+ /*
+ * CPM Block
+ */
+ rtems_unsigned16 cpcr;
+ rtems_unsigned16 _pad44;
+ rtems_unsigned16 rccr;
+ rtems_unsigned8 _pad45;
+ rtems_unsigned8 rmds;
+ rtems_unsigned32 rmdr;
+ rtems_unsigned16 rctr1;
+ rtems_unsigned16 rctr2;
+ rtems_unsigned16 rctr3;
+ rtems_unsigned16 rctr4;
+ rtems_unsigned16 _pad46;
+ rtems_unsigned16 rter;
+ rtems_unsigned16 _pad47;
+ rtems_unsigned16 rtmr;
+ rtems_unsigned8 _pad48[0x9f0-0x9dc];
+
+ /*
+ * BRG Block
+ */
+ rtems_unsigned32 brgc1;
+ rtems_unsigned32 brgc2;
+ rtems_unsigned32 brgc3;
+ rtems_unsigned32 brgc4;
+
+ /*
+ * SCC Block
+ */
+ m8xxSCCRegisters_t scc1;
+ m8xxSCCRegisters_t scc2;
+#if defined(mpc860)
+ m8xxSCCRegisters_t scc3;
+ m8xxSCCRegisters_t scc4;
+#elif defined(mpc821)
+ rtems_unsigned8 _pad72[0xa80-0xa40];
+#endif
+
+ /*
+ * SMC Block
+ */
+ m8xxSMCRegisters_t smc1;
+ m8xxSMCRegisters_t smc2;
+
+ /*
+ * SPI Block
+ */
+ rtems_unsigned16 spmode;
+ rtems_unsigned16 _pad49[2];
+ rtems_unsigned8 spie;
+ rtems_unsigned8 _pad50;
+ rtems_unsigned16 _pad51;
+ rtems_unsigned8 spim;
+ rtems_unsigned8 _pad52[2];
+ rtems_unsigned8 spcom;
+ rtems_unsigned16 _pad53[2];
+
+ /*
+ * PIP Block
+ */
+ rtems_unsigned16 pipc;
+ rtems_unsigned16 _pad54;
+ rtems_unsigned16 ptpr;
+ rtems_unsigned32 pbdir;
+ rtems_unsigned32 pbpar;
+ rtems_unsigned16 _pad55;
+ rtems_unsigned16 pbodr;
+ rtems_unsigned32 pbdat;
+ rtems_unsigned32 _pad56[6];
+
+ /*
+ * SI Block
+ */
+ rtems_unsigned32 simode;
+ rtems_unsigned8 sigmr;
+ rtems_unsigned8 _pad57;
+ rtems_unsigned8 sistr;
+ rtems_unsigned8 sicmr;
+ rtems_unsigned32 _pad58;
+ rtems_unsigned32 sicr;
+ rtems_unsigned16 sirp[2];
+ rtems_unsigned32 _pad59[3];
+ rtems_unsigned8 _pad60[0xc00-0xb00];
+ rtems_unsigned8 siram[512];
+#if defined(mpc860)
+ /*
+ * This is only used on the MPC8xxT - for the Fast Ethernet Controller (FEC)
+ */
+ m8xxFECRegisters_t fec;
+#elif defined(mpc821)
+ rtems_unsigned8 lcdram[512];
+#endif
+ rtems_unsigned8 _pad62[0x2000-0x1000];
+
+ /*
+ * Dual-port RAM
+ */
+ rtems_unsigned8 dpram0[0x200]; /* BD/DATA/UCODE */
+ rtems_unsigned8 dpram1[0x200]; /* BD/DATA/UCODE */
+ rtems_unsigned8 dpram2[0x400]; /* BD/DATA/UCODE */
+ rtems_unsigned8 dpram3[0x600]; /* BD/DATA*/
+ rtems_unsigned8 dpram4[0x200]; /* BD/DATA/UCODE */
+ rtems_unsigned8 _pad63[0x3c00-0x3000];
+
+ /* When using SCC1 for ethernet, we lose the use of I2C since
+ * their parameters would overlap. Motorola has a microcode
+ * patch to move parameters around so that both can be used
+ * together. It is available on their web site somewhere
+ * under http://www.mot.com/mpc8xx. If ethernet is used on
+ * one (or more) of the other SCCs, then other CPM features
+ * will be unavailable:
+ * SCC2 -> lose SPI
+ * SCC3 -> lose SMC1
+ * SCC4 -> lose SMC2
+ * However, Ethernet only works on SCC1 on the 8xx.
+ */
+ m8xxSCCENparms_t scc1p;
+ rtems_unsigned8 _rsv1[0xCB0-0xC00-sizeof(m8xxSCCENparms_t)];
+ m8xxMiscParms_t miscp;
+ rtems_unsigned8 _rsv2[0xcc0-0xCB0-sizeof(m8xxMiscParms_t)];
+ m8xxIDMAparms_t idma1p;
+ rtems_unsigned8 _rsv3[0xd00-0xcc0-sizeof(m8xxIDMAparms_t)];
+
+ m8xxSCCparms_t scc2p;
+ rtems_unsigned8 _rsv4[0xD80-0xD00-sizeof(m8xxSCCparms_t)];
+ m8xxSPIparms_t spip;
+ rtems_unsigned8 _rsv5[0xDB0-0xD80-sizeof(m8xxSPIparms_t)];
+ m8xxTimerParms_t tmp;
+ rtems_unsigned8 _rsv6[0xDC0-0xDB0-sizeof(m8xxTimerParms_t)];
+ m8xxIDMAparms_t idma2p;
+ rtems_unsigned8 _rsv7[0xE00-0xDC0-sizeof(m8xxIDMAparms_t)];
+
+ m8xxSCCparms_t scc3p; /* Not available on MPC821 */
+ rtems_unsigned8 _rsv8[0xE80-0xE00-sizeof(m8xxSCCparms_t)];
+ m8xxSMCparms_t smc1p;
+ rtems_unsigned8 _rsv9[0xEC0-0xE80-sizeof(m8xxSMCparms_t)];
+ m8xxDSPparms_t dsp1p;
+ rtems_unsigned8 _rsv10[0xF00-0xEC0-sizeof(m8xxDSPparms_t)];
+
+ m8xxSCCparms_t scc4p; /* Not available on MPC821 */
+ rtems_unsigned8 _rsv11[0xF80-0xF00-sizeof(m8xxSCCparms_t)];
+ m8xxSMCparms_t smc2p;
+ rtems_unsigned8 _rsv12[0xFC0-0xF80-sizeof(m8xxSMCparms_t)];
+ m8xxDSPparms_t dsp2p;
+ rtems_unsigned8 _rsv13[0x1000-0xFC0-sizeof(m8xxDSPparms_t)];
+} m8xx_t;
+
+extern volatile m8xx_t m8xx;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+
+#endif /* __MPC8xx_h */
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am
new file mode 100644
index 0000000000..322c3fca75
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/Makefile.am
@@ -0,0 +1,30 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/mmu.rel
+
+## C sources
+C_FILES = mmu.c
+
+clock_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(clock_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c
new file mode 100644
index 0000000000..7e877b106f
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c
@@ -0,0 +1,120 @@
+/*
+ * mmu.c
+ *
+ * This file contains routines for initializing
+ * and manipulating the MMU on the MPC8xx.
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+
+/*
+ * mmu_init
+ *
+ * This routine sets up the virtual memory maps on an MPC8xx.
+ * The MPC8xx does not support block address translation (BATs)
+ * and does not have segment registers. Thus, we must set up page
+ * translation. However, its MMU supports variable size pages
+ * (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
+ *
+ * The MPC8xx has separate data and instruction 32-entry translation
+ * lookaside buffers (TLB). By mapping all of DRAM as one huge page,
+ * we can preload the TLBs and not have to be concerned with taking
+ * TLB miss exceptions.
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+void mmu_init( void )
+{
+ register unsigned32 reg1, i;
+
+ /*
+ * Initialize the TLBs
+ *
+ * Instruction address translation and data address translation
+ * must be disabled during initialization (IR=0, DR=0 in MSR).
+ * We can assume the MSR has already been set this way.
+ */
+
+ /*
+ * Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
+ * GPM [0] 0b0 = PowerPC mode
+ * PPM [1] 0b0 = Page resolution of protection
+ * CIDEF [2] 0b0/0b1 = Default cache-inhibit attribute =
+ * NO for IMMU, YES for DMMU!
+ * reserved/WTDEF [3] 0b0 = Default write-through attribute = not
+ * RSV4x [4] 0b0 = 4 entries not reserved
+ * reserved/TWAM [5] 0b0/0b1 = 4-Kbyte page hardware assist
+ * PPCS [6] 0b0 = Ignore user/supervisor state
+ * reserved [7-18] 0x00
+ * xTLB_INDX [19-23] 31 = 0x1F
+ * reserved [24-31] 0x00
+ *
+ * Note: It is important that cache-inhibit be set as the default for the
+ * data cache when the DMMU is disabled in order to prevent internal memory
+ * mapped registers from being cached accidentally when address translation
+ * is turned off at the start of exception processing.
+ */
+ reg1 = M8xx_MI_CTR_ITLB_INDX(31);
+ _mtspr( M8xx_MI_CTR, reg1 );
+ reg1 = M8xx_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
+ _mtspr( M8xx_MD_CTR, reg1 );
+ _isync;
+
+ /*
+ * Invalidate all TLB entries in both TLBs.
+ * Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
+ * all 32 entries are invalidated.
+ */
+ __asm__ volatile ("tlbia\n"::);
+ _isync;
+
+ /*
+ * Set Current Address Space ID Register (M_CASID).
+ * Supervisor: CASID = 0
+ */
+ reg1 = 0;
+ _mtspr( M8xx_M_CASID, reg1 );
+
+ /*
+ * Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
+ * We ignore the Access Protection Group (APG) mechanism globally
+ * by setting all of the Mx_AP fields to 0b01 : client access
+ * permission is defined by page protection bits.
+ */
+ reg1 = 0x55555555;
+ _mtspr( M8xx_MI_AP, reg1 );
+ _mtspr( M8xx_MD_AP, reg1 );
+
+ /*
+ * Load both 32-entry TLBs with values from the MMU_TLB_table
+ * which is defined in the BSP.
+ * Note the _TLB_Table must have at most 32 entries. This code
+ * makes no effort to enforce this restriction.
+ */
+ for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
+ reg1 = MMU_TLB_table[i].mmu_epn;
+ _mtspr( M8xx_MI_EPN, reg1 );
+ _mtspr( M8xx_MD_EPN, reg1 );
+ reg1 = MMU_TLB_table[i].mmu_twc;
+ _mtspr( M8xx_MI_TWC, reg1 );
+ _mtspr( M8xx_MD_TWC, reg1 );
+ reg1 = MMU_TLB_table[i].mmu_rpn; /* RPN must be written last! */
+ _mtspr( M8xx_MI_RPN, reg1 );
+ _mtspr( M8xx_MD_RPN, reg1 );
+ }
+
+ /*
+ * Turn on address translation by setting MSR[IR] and MSR[DR].
+ */
+ _CPU_MSR_Value( reg1 );
+ reg1 |= PPC_MSR_IR | PPC_MSR_DR;
+ _CPU_MSR_SET( reg1 );
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/timer/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/timer/Makefile.am
new file mode 100644
index 0000000000..39f0c9f3b6
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/timer/Makefile.am
@@ -0,0 +1,30 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+PGM = ${ARCH}/timer.rel
+
+## C sources
+C_FILES = timer.c
+
+timer_rel_OBJECTS = $(C_FILES:%.c=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(timer_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = $(C_FILES)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/timer/timer.c b/c/src/lib/libcpu/powerpc/mpc8xx/timer/timer.c
new file mode 100644
index 0000000000..50c2a3e00a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/timer/timer.c
@@ -0,0 +1,104 @@
+/* timer.c
+ *
+ * This file manages the interval timer on the PowerPC MPC8xx.
+ * NOTE: This is not the PIT, but rather the RTEMS interval
+ * timer
+ * We shall use the bottom 32 bits of the timebase register,
+ *
+ * The following was in the 403 version of this file. I don't
+ * know what it means. JTM 5/19/98
+ * NOTE: It is important that the timer start/stop overhead be
+ * determined when porting or modifying this code.
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copywright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems.h>
+#include <mpc8xx.h>
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+static volatile rtems_unsigned32 Timer_starting;
+static rtems_boolean Timer_driver_Find_average_overhead;
+
+/*
+ * This is so small that this code will be reproduced where needed.
+ */
+static inline rtems_unsigned32 get_itimer(void)
+{
+ rtems_unsigned32 ret;
+
+ asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
+
+ return ret;
+}
+
+void Timer_initialize(void)
+{
+ /* set interrupt level and enable timebase. This should never */
+ /* generate an interrupt however. */
+ m8xx.tbscr |= M8xx_TBSCR_TBIRQ(4) | M8xx_TBSCR_TBE;
+
+ Timer_starting = get_itimer();
+}
+
+int Read_timer(void)
+{
+ rtems_unsigned32 clicks;
+ rtems_unsigned32 total;
+
+ clicks = get_itimer();
+
+ total = clicks - Timer_starting;
+
+ if ( Timer_driver_Find_average_overhead == 1 )
+ return total; /* in XXX microsecond units */
+
+ else {
+ if ( total < Cpu_table.timer_least_valid ) {
+ return 0; /* below timer resolution */
+ }
+ return (total - Cpu_table.timer_average_overhead);
+ }
+}
+
+rtems_status_code Empty_function(void)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+void Set_find_average_overhead(rtems_boolean find_flag)
+{
+ Timer_driver_Find_average_overhead = find_flag;
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/vectors/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/Makefile.am
new file mode 100644
index 0000000000..d82045bf32
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/Makefile.am
@@ -0,0 +1,33 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+## FIXME
+VPATH = @srcdir@:@srcdir@/../../ppc403/vectors
+
+PGM = ${ARCH}/vectors.rel
+
+## Assembly sources
+S_FILES = vectors.S align_h.S
+
+vectors_rel_OBJECTS = $(S_FILES:%.S=${ARCH}/%.o)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+AM_CFLAGS = $(CFLAGS_OS_V)
+
+$(PGM): $(vectors_rel_OBJECTS)
+ $(make-rel)
+
+all-local: ${ARCH} $(PGM)
+
+EXTRA_DIST = vectors.S README
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/vectors/README b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/README
new file mode 100644
index 0000000000..974c8bdd43
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/README
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+The location of the vectors file object is critical.
+
+From the comments at the head of vectors.S:
+
+ The issue with this file is getting it loaded at the right place.
+ The first vector MUST be at address 0x????0100.
+ How this is achieved is dependant on the tool chain.
+
+...
+
+ The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+ offset from 0x????0000 to the first location in the file. This
+ will be either 0x0000 or 0xfff0.
+
+The eth_comm BSP defines PPC_VECTOR_FILE_BASE to be 0x00000000.
+The MBX8xx BSP also defines PPC_VECTOR_FILE_BASE to be 0x00000000.
+Change these values to 0xFFF00000 if your are implementing an actual
+boot rom.
+
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/vectors/align_h.S b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/align_h.S
new file mode 100644
index 0000000000..ec8d11257c
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/align_h.S
@@ -0,0 +1,430 @@
+/* align_h.S 1.1 - 95/12/04
+ *
+ * This file contains the assembly code for the MPC860
+ * alignment exception handler for RTEMS.
+ *
+ * Based upon IBM provided code for the PowerPC 403 with the following release:
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *
+ * Modifications:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Additional modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
+ * Removed saving and restoring of PPC403-specific SRR2 and SRR3.
+ * Access DAR instead of PPC403-specific DEAR.
+ *
+ * $Id$
+ */
+
+#include "asm.h"
+#define ALIGN_REGS 0x0140
+
+.set CACHE_SIZE,16 # cache line size of 32 bytes
+.set CACHE_SIZE_L2,4 # cache line size, log 2
+
+.set Open_gpr0,0
+.set Open_gpr1,4
+.set Open_gpr2,8
+.set Open_gpr3,12
+.set Open_gpr4,16
+.set Open_gpr5,20
+.set Open_gpr6,24
+.set Open_gpr7,28
+.set Open_gpr8,32
+.set Open_gpr9,36
+.set Open_gpr10,40
+.set Open_gpr11,44
+.set Open_gpr12,48
+.set Open_gpr13,52
+.set Open_gpr14,56
+.set Open_gpr15,60
+.set Open_gpr16,64
+.set Open_gpr17,68
+.set Open_gpr18,72
+.set Open_gpr19,76
+.set Open_gpr20,80
+.set Open_gpr21,84
+.set Open_gpr22,88
+.set Open_gpr23,92
+.set Open_gpr24,96
+.set Open_gpr25,100
+.set Open_gpr26,104
+.set Open_gpr27,108
+.set Open_gpr28,112
+.set Open_gpr29,116
+.set Open_gpr30,120
+.set Open_gpr31,124
+.set Open_xer,128
+.set Open_lr,132
+.set Open_ctr,136
+.set Open_cr,140
+.set Open_srr0,144
+.set Open_srr1,148
+
+
+/*
+ * This code makes several assumptions for processing efficiency
+ * * General purpose registers are continuous in the image, beginning with
+ * Open_gpr0
+ * * Hash table is highly dependent on opcodes - opcode changes *will*
+ * require rework of the instruction decode mechanism.
+ */
+
+ .text
+ .globl align_h
+
+ .align CACHE_SIZE_L2
+align_h:
+ /*-----------------------------------------------------------------------
+ * Store GPRs in Open Reg save area
+ * Set up r2 as base reg, r1 pointing to Open Reg save area
+ *----------------------------------------------------------------------*/
+ stmw r0,ALIGN_REGS(r0)
+ li r1,ALIGN_REGS
+ /*-----------------------------------------------------------------------
+ * Store special purpose registers in reg save area
+ *----------------------------------------------------------------------*/
+ mfxer r7
+ mflr r8
+ mfcr r9
+ mfctr r10
+ stw r7,Open_xer(r1)
+ stw r8,Open_lr(r1)
+ stw r9,Open_cr(r1)
+ stw r10,Open_ctr(r1)
+ mfspr r9, srr0 /* SRR 0 */
+ mfspr r10, srr1 /* SRR 1 */
+ stw r9,Open_srr0(r1)
+ stw r10,Open_srr1(r1)
+
+/* Set up common registers */
+ mfspr r5, dar /* DAR: R5 is data (exception) address */
+ lwz r9,Open_srr0(r1) /* get faulting instruction */
+ addi r7,r9,4 /* bump instruction */
+ stw r7,Open_srr0(r1) /* restore to image */
+ lwz r9, 0(r9) /* retrieve actual instruction */
+ rlwinm r6,r9,18,25,29 /* r6 is RA * 4 field from instruction */
+ rlwinm r7,r9,6,26,31 /* r7 is primary opcode */
+ bl ref_point /* establish addressibility */
+ref_point:
+ mflr r11 /* r11 is the anchor point for ref_point */
+ addi r10, r7, -31 /* r10 = r7 - 31 */
+ rlwinm r10,r10,2,2,31 /* r10 *= 4 */
+ add r10, r10, r11 /* r10 += anchor point */
+ lwz r10, primary_jt-ref_point(r10)
+ mtlr r10
+ rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
+ la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
+ blr
+primary_jt:
+ .long xform
+ .long lwz
+ .long lwzu
+ .long 0
+ .long 0
+ .long stw
+ .long stwu
+ .long 0
+ .long 0
+ .long lhz
+ .long lhzu
+ .long lha
+ .long lhau
+ .long sth
+ .long sthu
+ .long lmw
+ .long stmw
+/*
+ * handlers
+ */
+/*
+ * xform instructions require an additional decode. Fortunately, a relatively
+ * simple hash step breaks the instructions out with no collisions
+ */
+xform:
+ rlwinm r7,r9,31,22,31 /* r7 is secondary opcode */
+ rlwinm r10,r7,27,5,31 /* r10 = r7 >> 5 */
+ add r10,r7,r10 /* r10 = r7 + r10 */
+ rlwinm r10,r10,2,25,29 /* r10 = (r10 & 0x1F) * 4 */
+ add r10,r10,r11 /* r10 += anchor point */
+ lwz r10, secondary_ht-ref_point(r10)
+ mtlr r10
+ la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
+ rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
+ blrl
+
+secondary_ht:
+ .long lhzux /* b 0 0x137 */
+ .long lhax /* b 1 0x157 */
+ .long lhaux /* b 2 0x177 */
+ .long sthx /* b 3 0x197 */
+ .long sthux /* b 4 0x1b7 */
+ .long 0 /* b 5 */
+ .long lwbrx /* b 6 0x216 */
+ .long 0 /* b 7 */
+ .long 0 /* b 8 */
+ .long 0 /* b 9 */
+ .long stwbrx /* b A 0x296 */
+ .long 0 /* b B */
+ .long 0 /* b C */
+ .long 0 /* b D */
+ .long lhbrx /* b E 0x316 */
+ .long 0 /* b F */
+ .long 0 /* b 10 */
+ .long 0 /* b 11 */
+ .long sthbrx /* b 12 0x396 */
+ .long 0 /* b 13 */
+ .long lwarx /* b 14 0x014 */
+ .long dcbz /* b 15 0x3f6 */
+ .long 0 /* b 16 */
+ .long lwzx /* b 17 0x017 */
+ .long lwzux /* b 18 0x037 */
+ .long 0 /* b 19 */
+ .long stwcx /* b 1A 0x096 */
+ .long stwx /* b 1B 0x097 */
+ .long stwux /* b 1C 0x0B7 */
+ .long 0 /* b 1D */
+ .long 0 /* b 1E */
+ .long lhzx /* b 1F 0x117 */
+
+/*
+ * for all handlers
+ * r4 - Addressability to interrupt context
+ * r5 - DAR address (faulting data address)
+ * r6 - RA field * 4
+ * r7 - Address of GPR 0 in image
+ * r8 - RD field * 4
+ * r9 - Failing instruction
+ */
+
+/* Load halfword algebraic with update */
+lhau:
+/* Load halfword algebraic with update indexed */
+lhaux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load halfword algebraic */
+lha:
+/* Load halfword algebraic indexed */
+lhax:
+ lswi r10,r5,2 /* load two bytes into r10 */
+ srawi r10,r10,16 /* shift right 2 bytes, extending sign */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/* Load Half Word Byte-Reversed Indexed */
+lhbrx:
+ lswi r10,r5,2 /* load two bytes from DEAR into r10 */
+ rlwinm r10,r10,0,0,15 /* mask off lower 2 bytes */
+ stwbrx r10,r7,r8 /* store reversed in reg image */
+ b align_complete /* return */
+
+/* Load Half Word and Zero with Update */
+lhzu:
+/* Load Half Word and Zero with Update Indexed */
+lhzux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load Half Word and Zero */
+lhz:
+/* Load Half Word and Zero Indexed */
+lhzx:
+ lswi r10,r5,2 /* load two bytes from DEAR into r10 */
+ rlwinm r10,r10,16,16,31 /* shift right 2 bytes, with zero fill */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/*
+ * Load Multiple Word
+ */
+lmw:
+ lwzx r9,r6,r7 /* R9 contains saved value of RA */
+ addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
+ rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
+ subfic r8,r8,32 /* r8 is reg count to load */
+ mtctr r8 /* load counter */
+ addi r8,r8,-1 /* r8-- */
+ rlwinm r8,r8,2,2,31 /* r8 *= 4 */
+ add r5,r5,r8 /* update DEAR to point to last reg */
+lwmloop:
+ lswi r11,r5,4 /* load r11 with 4 bytes from DEAR */
+ stwu r11,-4(r10) /* load image and decrement pointer */
+ addi r5,r5,-4 /* decrement effective address */
+ bdnz lwmloop
+ stwx r9,r6,r7 /* restore RA (in case it was trashed) */
+ b align_complete /* return */
+
+/*
+ * Load Word and Reserve Indexed
+ */
+lwarx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwx r10,r7,r8 /* update reg image */
+ rlwinm r5,r5,0,0,29 /* Word align address */
+ lwarx r10,0,r5 /* Set reservation */
+ b align_complete /* return */
+
+/*
+ * Load Word Byte-Reversed Indexed
+ */
+lwbrx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwbrx r10,r7,r8 /* store reversed in reg image */
+ b align_complete /* return */
+
+/* Load Word and Zero with Update */
+lwzu:
+/* Load Word and Zero with Update Indexed */
+lwzux:
+ stwx r5,r7,r6 /* update RA with effective addr */
+
+/* Load Word and Zero */
+lwz:
+/* Load Word and Zero Indexed */
+lwzx:
+ lswi r10,r5,4 /* load four bytes from DEAR into r10 */
+ stwx r10,r7,r8 /* update reg image */
+ b align_complete /* return */
+
+/* Store instructions */
+
+/* */
+/* Store Half Word and Update */
+sthu:
+/* Store Half Word and Update Indexed */
+sthux:
+ stwx r5,r7,r6 /* Update RA with effective address */
+
+/* Store Half Word */
+sth:
+/* Store Half Word Indexed */
+sthx:
+ lwzx r10,r8,r7 /* retrieve source register value */
+ rlwinm r10,r10,16,0,15 /* move two bytes to high end of reg */
+ stswi r10,r5,2 /* store bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Half Word Byte-Reversed Indexed */
+sthbrx:
+ lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
+ stswi r10,r5,2 /* move two bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Multiple Word */
+stmw:
+ addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
+ rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
+ subfic r8,r8,32 /* r8 is reg count to load */
+ mtctr r8 /* load counter */
+ addi r8,r8,-1 /* r8-- */
+ rlwinm r8,r8,2,2,31 /* r8 *= 4 */
+ add r5,r5,r8 /* update DEAR to point to last reg */
+stmloop:
+ lwzu r11,-4(r10) /* get register value */
+ stswi r11,r5,4 /* output to DEAR address */
+ addi r5,r5,-4 /* decrement effective address */
+ bdnz stmloop
+ b align_complete /* return */
+
+/* */
+/* Store Word and Update */
+stwu:
+/* Store Word and Update Indexed */
+stwux:
+ stwx r5,r7,r6 /* Update RA with effective address */
+
+/* Store Word */
+stw:
+/* Store Word Indexed */
+stwx:
+ lwzx r10,r8,r7 /* retrieve source register value */
+ stswi r10,r5,4 /* store bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Word Byte-Reversed Indexed */
+stwbrx:
+ lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
+ stswi r10,r5,4 /* move two bytes to DEAR address */
+ b align_complete /* return */
+
+/* */
+/* Store Word Conditional Indexed */
+stwcx:
+ rlwinm r10,r5,0,0,29 /* r10 = word aligned DEAR */
+ lwz r11,0(r10) /* save original value of store */
+ stwcx. r11,r0,r10 /* attempt store to address */
+ bne stwcx_moveon /* store failed, move on */
+ stw r11,0(r10) /* repair damage */
+ lwzx r9,r7,r8 /* get register value */
+ stswi r10,r5,4 /* store bytes to DEAR address */
+stwcx_moveon:
+ mfcr r11 /* get condition reg */
+ lwz r9,Open_cr(r1) /* get condition reg image */
+ rlwimi r9,r11,0,0,2 /* insert 3 CR bits into cr image */
+ lwz r11,Open_xer(r1) /* get XER reg */
+ rlwimi r9,r11,29,2,2 /* insert XER SO bit into cr image */
+ stw r9,Open_cr(r1) /* store cr image */
+ b align_complete /* return */
+
+/* */
+/* Data Cache Block Zero */
+dcbz:
+ rlwinm r5,r5,0,0,31-CACHE_SIZE_L2
+ /* get address to nearest Cache line */
+ addi r5,r5,-4 /* adjust by a word */
+ addi r10,r0,CACHE_SIZE/4 /* set counter value */
+ mtctr r10
+ addi r11,r0,0 /* r11 = 0 */
+dcbz_loop:
+ stwu r11,4(r5) /* store a word and update EA */
+ bdnz dcbz_loop
+ b align_complete /* return */
+
+align_complete:
+ /*-----------------------------------------------------------------------
+ * Restore regs and return from the interrupt
+ *----------------------------------------------------------------------*/
+ lmw r26,Open_xer+ALIGN_REGS(r0)
+ mtxer r26
+ mtlr r27
+ mtctr r28
+ mtcrf 0xFF, r29
+ mtspr srr0, r30 /* SRR 0 */
+ mtspr srr1, r31 /* SRR 1 */
+ lmw r1,Open_gpr1+ALIGN_REGS(r0)
+ lwz r0,Open_gpr0+ALIGN_REGS(r0)
+ rfi
diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/vectors/vectors.S b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/vectors.S
new file mode 100644
index 0000000000..43e6f1f056
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc8xx/vectors/vectors.S
@@ -0,0 +1,1300 @@
+/* vectors.S 1.1 - 95/12/04
+ *
+ * This file contains the assembly code for the PowerPC MPC8xx
+ * interrupt veneers for RTEMS.
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ *
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libcpu/ppc/ppc403/vectors/vectors.s:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Dwarf debugging info added by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
+ * Also, made changes to turn address translation back on.
+ *
+ * Modifications for to add DWARF debugging info, turn address translation on
+ * and to coexist with EPPCBug:
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ */
+
+/*
+ * The issue with this file is getting it loaded at the right place.
+ * The first vector MUST be at address 0x????0100.
+ * How this is achieved is dependant on the tool chain.
+ *
+ * However the basic mechanism for ELF assemblers is to create a
+ * section called ".vectors", which will be loaded to an address
+ * between 0x????0000 and 0x????0100 (inclusive) via a link script.
+ *
+ * The basic mechanism for XCOFF assemblers is to place it in the
+ * normal text section, and arrange for this file to be located
+ * at an appropriate position on the linker command line.
+ *
+ * The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+ * offset from 0x????0000 to the first location in the file. This
+ * will be either 0x0000 or 0xfff0.
+ *
+ * If EPPCBUG_VECTORS is #defined, vectors 0x100 (system reset),
+ * 0x700 (program), 0xC00 (system call) and 0xD00 (trace) are set
+ * up identically to the EPPCBug vectors in order to preserve the
+ * firmware runtime environment.
+ *
+ * THE FOUR ABOVE VECTORS MAY NEED TO BE MODIFIED TO MATCH YOUR
+ * REVISION OF THE FIRMWARE.
+ *
+ * Coexisting with the firmware only makes sense when the
+ * PPC_VECTOR_FILE_BASE is 0.
+ *
+ * $Id$
+ */
+
+#include "asm.h"
+#include <mpc8xx.h>
+
+/* Location of your rtems source tree for source-level debugging purposes */
+#define PATH_PREFIX "/home/stewart"
+
+#ifndef PPC_VECTOR_FILE_BASE
+#error "PPC_VECTOR_FILE_BASE is not defined."
+#endif
+
+ /* Where this file will be loaded */
+ .set file_base, PPC_VECTOR_FILE_BASE
+
+ /* Offset to store reg 0 */
+
+ .set IP_LINK, 0
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+ .set IP_0, (IP_LINK + 56)
+#else
+ .set IP_0, (IP_LINK + 8)
+#endif
+ .set IP_2, (IP_0 + 4)
+
+ .set IP_3, (IP_2 + 4)
+ .set IP_4, (IP_3 + 4)
+ .set IP_5, (IP_4 + 4)
+ .set IP_6, (IP_5 + 4)
+
+ .set IP_7, (IP_6 + 4)
+ .set IP_8, (IP_7 + 4)
+ .set IP_9, (IP_8 + 4)
+ .set IP_10, (IP_9 + 4)
+
+ .set IP_11, (IP_10 + 4)
+ .set IP_12, (IP_11 + 4)
+ .set IP_13, (IP_12 + 4)
+ .set IP_28, (IP_13 + 4)
+
+ .set IP_29, (IP_28 + 4)
+ .set IP_30, (IP_29 + 4)
+ .set IP_31, (IP_30 + 4)
+ .set IP_CR, (IP_31 + 4)
+
+ .set IP_CTR, (IP_CR + 4)
+ .set IP_XER, (IP_CTR + 4)
+ .set IP_LR, (IP_XER + 4)
+ .set IP_PC, (IP_LR + 4)
+
+ .set IP_MSR, (IP_PC + 4)
+
+ .set IP_END, (IP_MSR + 16)
+
+ /* Vector offsets */
+ .set begin_vector, 0x0000
+ .set reset_vector, 0x0100
+ .set mach_vector, 0x0200
+ .set dsi_vector, 0x0300
+ .set isi_vector, 0x0400
+ .set ext_vector, 0x0500
+ .set align_vector, 0x0600
+ .set prog_vector, 0x0700
+ .set float_vector, 0x0800
+ .set dec_vector, 0x0900
+ .set sys_vector, 0x0C00
+ .set trace_vector, 0x0d00
+ .set syscall_vector, 0x0c00
+ .set fpassist_vector, 0x0e00
+ .set software_vector, 0x1000
+ .set itlbm_vector, 0x1100
+ .set dtlbm_vector, 0x1200
+ .set itlbe_vector, 0x1300
+ .set dtlbe_vector, 0x1400
+ .set databkpt_vector, 0x1c00
+ .set insbkpt_vector, 0x1d00
+ .set perbkpt_vector, 0x1e00
+ .set dev_vector, 0x1f00
+ .set siu_vector, 0x2000
+ .set cpm_vector, 0x2400
+
+/* Go to the right section */
+#if PPC_ASM == PPC_ASM_XCOFF
+ .csect .text[PR]
+#elif PPC_ASM == PPC_ASM_ELF
+ .section .vectors,"awx",@progbits
+.L_text_b:
+.L_LC1:
+ .previous
+
+.section .debug_sfnames
+.L_sfnames_b:
+ .byte PATH_PREFIX"rtems/c/src/lib/libcpu/powerpc/mpc8xx/vectors/"
+ .byte 0
+.L_F0:
+ .byte "vectors.S"
+ .byte 0
+ .previous
+
+.section .line
+.L_line_b:
+ .4byte .L_line_e-.L_line_b
+ .4byte .L_text_b
+.L_LE1:
+.L_line_last:
+ .4byte 0x0
+ .2byte 0xffff
+ .4byte .L_text_e-.L_text_b
+.L_line_e:
+ .previous
+
+.section .debug_srcinfo
+.L_srcinfo_b:
+ .4byte .L_line_b
+ .4byte .L_sfnames_b
+ .4byte .L_text_b
+ .4byte .L_text_e
+ .4byte 0xffffffff
+ .4byte .L_LE1-.L_line_b
+ .4byte .L_F0-.L_sfnames_b
+ .4byte .L_line_last-.L_line_b
+ .4byte 0xffffffff
+ .previous
+
+.section .debug_pubnames
+ .4byte .L_debug_b
+ .4byte .L_P0
+ .byte "__vectors"
+ .byte 0
+ .4byte 0x0
+ .byte 0
+ .previous
+
+.section .debug_aranges
+ .4byte .L_debug_b
+ .4byte .L_text_b
+ .4byte .L_text_e-.L_text_b
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0
+ .4byte 0x0
+ .4byte 0x0
+ .previous
+
+.section .debug
+.L_debug_b:
+.L_D1:
+ .4byte .L_D1_e-.L_D1
+ .2byte 0x11 /* TAG_compile_unit */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D2
+ .2byte 0x38 /* AT_name */
+ .byte "vectors.S"
+ .byte 0
+ .2byte 0x258 /* AT_producer */
+ .byte "GAS 2.5.2"
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x106 /* AT_stmt_list */
+ .4byte .L_line_b
+ .2byte 0x1b8 /* AT_comp_dir */
+ .byte PATH_PREFIX"rtems/c/src/lib/libcpu/powerpc/mpc8xx/vectors/"
+ .byte 0
+ .2byte 0x8006 /* AT_sf_names */
+ .4byte .L_sfnames_b
+ .2byte 0x8016 /* AT_src_info */
+ .4byte .L_srcinfo_b
+.L_D1_e:
+.L_P0:
+.L_D3:
+ .4byte .L_D3_e-.L_D3
+ .2byte 0x6 /* TAG_global_subroutine */
+ .2byte 0x12 /* AT_sibling */
+ .4byte .L_D4
+ .2byte 0x38 /* AT_name */
+ .byte "__vectors"
+ .byte 0
+ .2byte 0x278 /* AT_prototyped */
+ .byte 0
+ .2byte 0x111 /* AT_low_pc */
+ .4byte .L_text_b
+ .2byte 0x121 /* AT_high_pc */
+ .4byte .L_text_e
+ .2byte 0x8041 /* AT_body_begin */
+ .4byte .L_text_b
+ .2byte 0x8051 /* AT_body_end */
+ .4byte .L_text_e
+.L_D3_e:
+
+.L_D4:
+ .4byte .L_D4_e-.L_D4
+ .align 2
+.L_D4_e:
+.L_D2:
+ .previous
+
+ .section .vectors
+#endif /* PPC_ASM_ELF */
+
+ PUBLIC_VAR (__vectors)
+SYM (__vectors):
+
+
+/* 0x100 -- Critical error handling */
+ .org reset_vector - file_base
+base_vectors:
+
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE003EF8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif /* PPC_HAS_FPU */
+#else
+ stwu r1, -(IP_END)(r1)
+#endif /* PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27 */
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_SYSTEM_RESET
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x200 -- Machine check exception */
+ .org mach_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE003DF8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_MCHECK
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x300 -- Protection exception */
+ .org dsi_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE003CF8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_PROTECT
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x400 -- Instruction Storage exception */
+ .org isi_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE003BF8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_ISI
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x500 -- External interrupt */
+/* When an external interrupt occurs, we must find out what caused it */
+/* before calling the RTEMS handler. First we use SIVEC to decide */
+/* what signalled the interrupt to the SIU. */
+ .org ext_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ stw r9, IP_9(r1) /* r9 will be restored in the next level */
+ stw r10, IP_10(r1)
+
+ lis r9, m8xx@ha
+ addi r9, r9, m8xx@l
+ lbz r10, 0x1c(r9) /* SIVEC */
+ rlwinm r10, r10, 4, 0, 27 /* each psuedo vector will have */
+ /* room for 16 instructions */
+ addis r10, r10, siu_vectors@ha
+ addi r10, r10, siu_vectors@l
+ mflr r0
+ mtlr r10
+ lwz r10, IP_10(r1)
+ blr
+
+
+/* 0x600 -- Align exception */
+ .org align_vector - file_base
+ .extern align_h
+ b align_h
+
+
+/* 0x700 -- Program exception */
+ .org prog_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0038F8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_PROGRAM
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x800 -- Float exception */
+ .org float_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0037F8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_NOFP
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x900 -- Decrementer exception */
+ .org dec_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_DECREMENTER
+ b PROC (_ISR_Handler)
+
+
+/* 0xC00 -- System call */
+ .org sys_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0033F8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_SCALL
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0xD00 -- Trace interrupt */
+ .org trace_vector - file_base
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0032F8 /* 0xFE004004 */
+#else
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+ stwu r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+ stwu r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+ stwu r1, -(IP_END)(r1)
+#endif
+ stw r0, IP_0(r1)
+
+ /* Turn address translation back on to re-enable the caches. */
+ mfmsr r0
+ ori r0, r0, 0x30
+ mtmsr r0
+
+ li r0, PPC_IRQ_TRACE
+ b PROC (_ISR_Handler)
+#endif /* EPPCBUG_VECTORS */
+
+
+#ifdef EPPCBUG_VECTORS
+/* 0xE00 -- Floating Point Assist */
+ .org fpassist_vector - file_base
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0031F8 /* 0xFE004004 */
+
+/* 0x1000 -- Software Emulation */
+ .org software_vector - file_base
+software_vectors:
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE002FF8 /* 0xFE004004 */
+#endif
+
+
+/* 0x1100 -- Intruction TLB Miss */
+ .org itlbm_vector - file_base
+itlbm_vectors:
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE002EF8 /* 0xFE004004 */
+#else
+ mfspr r2, 784 /* MI_CTR */
+ mfspr r3, 792 /* MD_CTR */
+ mfspr r4, 787 /* MI_EPN */
+ mfspr r5, 789 /* MI_TWC */
+ mfspr r6, 797 /* MD_TWC */
+ mfspr r7, 789 /* MI_TWC */
+ mfspr r8, 790 /* MI_RPN */
+ mfspr r9, 798 /* MD_RPN */
+ mfspr r10, 796 /* M_TWB */
+ mfspr r11, 793 /* M_CASID */
+ mfspr r12, 786 /* MI_AP */
+ mfspr r13, 794 /* MD_AP */
+ mfspr r14, 799 /* M_TW */
+ mfspr r15, 816 /* MI_CAM */
+ mfspr r16, 817 /* MI_RAM0 */
+ mfspr r17, 818 /* MI_RAM1 */
+ mfspr r18, 824 /* MD_CAM */
+ mfspr r19, 825 /* M_RAM0 */
+ mfspr r20, 826 /* M_RAM1 */
+ .long 0
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x1200 -- Data TLB Miss */
+ .org dtlbm_vector - file_base
+dtlbm_vectors:
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE002DF8 /* 0xFE004004 */
+#else
+ mfspr r1, 0x1a
+ mfspr r2, 784 /* MI_CTR */
+ mfspr r3, 792 /* MD_CTR */
+ lis r3, 0x400
+ mtspr 792, r3
+ mfspr r4, 787 /* MI_EPN */
+ mfspr r5, 789 /* MI_TWC */
+ mfspr r6, 797 /* MD_TWC */
+ mfspr r7, 789 /* MI_TWC */
+ mfspr r8, 790 /* MI_RPN */
+ mfspr r9, 798 /* MD_RPN */
+ mfspr r10, 796 /* M_TWB */
+ mfspr r11, 793 /* M_CASID */
+ mfspr r12, 786 /* MI_AP */
+ mfspr r13, 794 /* MD_AP */
+ mfspr r14, 799 /* M_TW */
+ mfspr r15, 816 /* MI_CAM */
+ mfspr r16, 817 /* MI_RAM0 */
+ mfspr r17, 818 /* MI_RAM1 */
+ mtspr 824, r18
+ mfspr r18, 824 /* MD_CAM */
+ mfspr r19, 825 /* M_RAM0 */
+ mfspr r20, 826 /* M_RAM1 */
+ .long 0
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x1300 -- Instruction TLB Error */
+ .org itlbe_vector - file_base
+itlbe_vectors:
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE002CF8 /* 0xFE004004 */
+#else
+ mfspr r2, 784 /* MI_CTR */
+ mfspr r3, 792 /* MD_CTR */
+ mfspr r4, 787 /* MI_EPN */
+ mfspr r5, 789 /* MI_TWC */
+ mfspr r6, 797 /* MD_TWC */
+ mfspr r7, 789 /* MI_TWC */
+ mfspr r8, 790 /* MI_RPN */
+ mfspr r9, 798 /* MD_RPN */
+ mfspr r10, 796 /* M_TWB */
+ mfspr r11, 793 /* M_CASID */
+ mfspr r12, 786 /* MI_AP */
+ mfspr r13, 794 /* MD_AP */
+ mfspr r14, 799 /* M_TW */
+ mfspr r15, 816 /* MI_CAM */
+ mfspr r16, 817 /* MI_RAM0 */
+ mfspr r17, 818 /* MI_RAM1 */
+ mfspr r18, 824 /* MD_CAM */
+ mfspr r19, 825 /* M_RAM0 */
+ mfspr r20, 826 /* M_RAM1 */
+ .long 0
+#endif /* EPPCBUG_VECTORS */
+
+
+/* 0x1400 -- Data TLB Error */
+ .org dtlbe_vector - file_base
+dtlbe_vectors:
+#ifdef EPPCBUG_VECTORS
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE002BF8 /* 0xFE004004 */
+#else
+ mfspr r2, 784 /* MI_CTR */
+ mfspr r3, 792 /* MD_CTR */
+ mfspr r4, 787 /* MI_EPN */
+ mfspr r5, 789 /* MI_TWC */
+ mfspr r6, 797 /* MD_TWC */
+ mfspr r7, 789 /* MI_TWC */
+ mfspr r8, 790 /* MI_RPN */
+ mfspr r9, 798 /* MD_RPN */
+ mfspr r10, 796 /* M_TWB */
+ mfspr r11, 793 /* M_CASID */
+ mfspr r12, 786 /* MI_AP */
+ mfspr r13, 794 /* MD_AP */
+ mfspr r14, 799 /* M_TW */
+ mfspr r15, 816 /* MI_CAM */
+ mfspr r16, 817 /* MI_RAM0 */
+ mfspr r17, 818 /* MI_RAM1 */
+ mfspr r18, 824 /* MD_CAM */
+ mfspr r19, 825 /* M_RAM0 */
+ mfspr r20, 826 /* M_RAM1 */
+ .long 0
+#endif /* EPPCBUG_VECTORS */
+
+
+#ifdef EPPCBUG_VECTORS
+/* 0x1C00 -- Data Breakpoint */
+ .org databkpt_vector - file_base
+databkpt_vectors:
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0023F8 /* 0xFE004004 */
+
+/* 0x1D00 -- Instruction Breakpoint */
+ .org insbkpt_vector - file_base
+insbkpt_vectors:
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0022F8 /* 0xFE004004 */
+
+/* 0x1E00 -- Peripheral Breakpoint */
+ .org perbkpt_vector - file_base
+perbkpt_vectors:
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0021F8 /* 0xFE004004 */
+
+/* 0x1F00 -- Non-Makable Development Port */
+ .org dev_vector - file_base
+dev_vectors:
+ mtsprg 0, r1
+ mflr r1
+ mtsprg 1, r1
+ bl 0xFE0020F8 /* 0xFE004004 */
+#endif
+
+
+
+/* Now we look at what signaled the interrupt to the SIU. */
+/* I needed to do this in order to decode the CPM interrupts before */
+/* calling _ISR_Handler */
+
+/* *IRQ0 */
+ .org siu_vector - file_base
+siu_vectors:
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ0
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 0 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL0
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ1
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* This is probably not the "correct" way to do this. I need to have a
+ * way of calling _ISR_Handler for the CPM interrupts and this is the
+ * simplest way I can think of. Since I have the CPM interrupt mapped
+ * to the SIU interrupt level 1 on the eth-comm board, I put it here.
+ * It would probably be ok if I moved this directory to under libbsp
+ * instead of libcpu. For now, deal with it.
+*/
+/* Level 1 - CPM */
+/* Now we need to get the CPM interrupt vector */
+ /* Registers: */
+ /* R0 - has stored value of LR */
+ /* R9 - pointer to m8xx struct */
+ /* R10 has already been saved and restored */
+ li r10, 1
+ sth r10, 0x930(r9) /* CIVR */
+ lbz r10, 0x930(r9) /* if we use this as an offset into a */
+ rlwinm r10, r10, 1, 0, 31 /* table, each entry will have room */
+ /* 4 instructions. */
+ addis r10, r10, cpm_vectors@ha
+ addi r10, r10, cpm_vectors@l
+
+ mtlr r10
+ lwz r10, IP_10(r1)
+ blr
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+#if 0
+/* Level 1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL1
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+#endif
+
+/* *IRQ2 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ2
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 2 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL2
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ3 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ3
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 3 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL3
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ4 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ4
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 4 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL4
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ5 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ5
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 5 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL5
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ6 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ6
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 6 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL6
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* *IRQ7 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_IRQ7
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+/* Level 7 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_LVL7
+ b PROC (_ISR_Handler)
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+
+/* .org cpm_vector - file_base*/
+cpm_vectors:
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_ERROR
+ b PROC (_ISR_Handler)
+
+ /* PC4 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC4
+ b PROC (_ISR_Handler)
+
+ /* PC5 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC5
+ b PROC (_ISR_Handler)
+
+ /* SMC2 / PIP */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SMC2
+ b PROC (_ISR_Handler)
+
+ /* SMC1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SMC1
+ b PROC (_ISR_Handler)
+
+ /* SPI */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SPI
+ b PROC (_ISR_Handler)
+
+ /* PC6 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC6
+ b PROC (_ISR_Handler)
+
+ /* Timer 4 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_TIMER4
+ b PROC (_ISR_Handler)
+
+ /* Reserved - we should never see this */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_RESERVED_8
+ .long 0
+
+ /* PC7 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC7
+ b PROC (_ISR_Handler)
+
+ /* PC8 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC8
+ b PROC (_ISR_Handler)
+
+ /* PC9 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC9
+ b PROC (_ISR_Handler)
+
+ /* Timer 3 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_TIMER3
+ b PROC (_ISR_Handler)
+
+ /* Reserved - we should never get here */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_RESERVED_D
+ .long 0
+
+ /* PC10 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC10
+ b PROC (_ISR_Handler)
+
+ /* PC11 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC11
+ b PROC (_ISR_Handler)
+
+ /* I2C */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_I2C
+ b PROC (_ISR_Handler)
+
+ /* RISC Timer Table */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_RISC_TIMER
+ b PROC (_ISR_Handler)
+
+ /* Timer 2 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_TIMER2
+ b PROC (_ISR_Handler)
+
+ /* Reserved - we should never get here */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_RESERVED_13
+ .long 0
+
+ /* IDMA2 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_IDMA2
+ b PROC (_ISR_Handler)
+
+ /* IDMA1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_IDMA1
+ b PROC (_ISR_Handler)
+
+ /* SDMA Channel Bus Error */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SDMA_ERROR
+ b PROC (_ISR_Handler)
+
+ /* PC12 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC12
+ b PROC (_ISR_Handler)
+
+ /* PC13 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC13
+ b PROC (_ISR_Handler)
+
+ /* Timer 1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_TIMER1
+ b PROC (_ISR_Handler)
+
+ /* PC14 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC14
+ b PROC (_ISR_Handler)
+
+ /* SCC4 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SCC4
+ b PROC (_ISR_Handler)
+
+ /* SCC3 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SCC3
+ b PROC (_ISR_Handler)
+
+ /* SCC2 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SCC2
+ b PROC (_ISR_Handler)
+
+ /* SCC1 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_SCC1
+ b PROC (_ISR_Handler)
+
+ /* PC15 */
+ mtlr r0
+ lwz r9, IP_9(r1)
+ li r0, PPC_IRQ_CPM_PC15
+ b PROC (_ISR_Handler)
+
+.L_text_e:
+
+
diff --git a/c/src/lib/libcpu/powerpc/old-exceptions/cpu.c b/c/src/lib/libcpu/powerpc/old-exceptions/cpu.c
index 7d6824cb26..5a5fadfd97 100644
--- a/c/src/lib/libcpu/powerpc/old-exceptions/cpu.c
+++ b/c/src/lib/libcpu/powerpc/old-exceptions/cpu.c
@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
+int _CPU_spurious_count = 0;
+int _CPU_last_spurious = 0;
+
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
+ ++_CPU_spurious_count;
+ _CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
- case PPC_IRQ_CPM_RESERVED_0:
+ case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:
diff --git a/c/src/lib/libcpu/powerpc/old_exception_processing/Makefile.am b/c/src/lib/libcpu/powerpc/old_exception_processing/Makefile.am
index 9629808140..92f3fee811 100644
--- a/c/src/lib/libcpu/powerpc/old_exception_processing/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/old_exception_processing/Makefile.am
@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
-C_FILES = cpu.c ppccache.c
+C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =
diff --git a/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.c b/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.c
index 7d6824cb26..5a5fadfd97 100644
--- a/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.c
+++ b/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.c
@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
+int _CPU_spurious_count = 0;
+int _CPU_last_spurious = 0;
+
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
+ ++_CPU_spurious_count;
+ _CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
- case PPC_IRQ_CPM_RESERVED_0:
+ case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:
diff --git a/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.h b/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.h
index 2a502d0745..30dd6dc092 100644
--- a/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.h
+++ b/c/src/lib/libcpu/powerpc/old_exception_processing/cpu.h
@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
+#define _CPU_Data_Cache_Block_Invalidate( _address ) \
+ do { register void *__address = (_address); \
+ register unsigned32 _zero = 0; \
+ asm volatile ( "dcbi %0,%1" : \
+ "=r" (_zero), "=r" (__address) : \
+ "0" (_zero), "1" (__address) \
+ ); \
+ } while (0)
+
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
diff --git a/c/src/lib/libcpu/powerpc/shared/cpu.h b/c/src/lib/libcpu/powerpc/shared/cpu.h
index 3fe27f5496..374ea6c54c 100644
--- a/c/src/lib/libcpu/powerpc/shared/cpu.h
+++ b/c/src/lib/libcpu/powerpc/shared/cpu.h
@@ -1,7 +1,7 @@
/*
* cpu.h
*
- * This file contains some powerpc MSR and registers access definitions.
+ * This file contains some powerpc MSR and registers access definitions.
*
* It is a stripped down version of linux ppc processor.h file...
*
@@ -15,10 +15,12 @@
* $Id$
*/
-#ifndef __ASM_PPC_PROCESSOR_H
-#define __ASM_PPC_PROCESSOR_H
+#ifndef __PPC_CPU_H
+#define __PPC_CPU_H
-#include <bsp/residual.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
/* Bit encodings for Machine State Register (MSR) */
#define MSR_POW (1<<18) /* Enable Power Management */
@@ -247,16 +249,6 @@ static inline void PPC_Set_timebase_register (unsigned long long tbr)
}
-#define _CPU_Data_Cache_Block_Flush( _address ) \
- do { register void *__address = (_address); \
- register unsigned32 _zero = 0; \
- asm volatile ( "dcbf %0,%1" : \
- "=r" (_zero), "=r" (__address) : \
- "0" (_zero), "1" (__address) \
- ); \
- } while (0)
-
-
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
@@ -325,7 +317,12 @@ static inline void PPC_Set_timebase_register (unsigned long long tbr)
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
} while (0)
-#endif /* __ASM_PPC_PROCESSOR_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PPC_CPU_H */
diff --git a/c/src/make/compilers/gcc-target-default.cfg b/c/src/make/compilers/gcc-target-default.cfg
index fb5dfbad62..c0baabb6d4 100644
--- a/c/src/make/compilers/gcc-target-default.cfg
+++ b/c/src/make/compilers/gcc-target-default.cfg
@@ -88,17 +88,26 @@ endif
# debug flag;
CFLAGS_DEBUG_V+=-Wno-unused
+CXXFLAGS_DEBUG_V+=
ifeq ($(RTEMS_USE_GCC272),no)
CFLAGS_DEBUG_V+=-qrtems_debug
+CXXFLAGS_DEBUG_V+=-qrtems_debug
endif
+# when debugging, optimize flag: typically empty
+# some compilers do allow optimization with their "-g"
+CFLAGS_DEBUG_OPTIMIZE_V=-g
+CXXFLAGS_DEBUG_OPTIMIZE_V=-g
+
# profile flag; use gprof(1)
CFLAGS_PROFILE_V=-pg
+CXXFLAGS_PROFILE_V=-pg
ifndef AUTOMAKE
# default is to optimize
-CFLAGS_OPTIMIZE=$(CFLAGS_OPTIMIZE_V)
+CFLAGS_OPTIMIZE =$(CFLAGS_OPTIMIZE_V)
+CXXFLAGS_OPTIMIZE=$(CXXFLAGS_OPTIMIZE_V)
endif
# dynamic libraries
@@ -106,7 +115,8 @@ endif
#ASFLAGS_DYNAMIC_V=
ifndef AUTOMAKE
-CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
+CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
+CXXFLAGS += $(CXXFLAGS_OPTIMIZE) $(CXXFLAGS_DEBUG) $(CXXFLAGS_PROFILE)
endif
# List of library paths without -L
diff --git a/c/src/tests/configure.in b/c/src/tests/configure.in
index 2bbfb374f7..e07aeb847e 100644
--- a/c/src/tests/configure.in
+++ b/c/src/tests/configure.in
@@ -67,6 +67,7 @@ AC_SUBST(BARE_CPU_MODEL)
AC_CONFIG_SUBDIRS(tools)
AC_CONFIG_SUBDIRS(support)
AC_CONFIG_SUBDIRS(samples)
+AC_CONFIG_SUBDIRS(libffi)
AC_CONFIG_SUBDIRS($cfg_subdirs)
# Explicitly list all Makefiles here
diff --git a/c/src/tests/libtests/termios/init.c b/c/src/tests/libtests/termios/init.c
index bc4097a8cc..37e6506eea 100644
--- a/c/src/tests/libtests/termios/init.c
+++ b/c/src/tests/libtests/termios/init.c
@@ -24,6 +24,7 @@
#include <bsp.h>
+
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
@@ -587,6 +588,7 @@ void change_line_settings( struct termios *tp )
void canonical_input( struct termios *tp )
{
+ char buffer[256];
char c, first_time = TRUE;
printf( "\nTesting canonical input\n\n" );
@@ -612,6 +614,7 @@ void canonical_input( struct termios *tp )
printf( "\n\nCanonical input test done.\n" );
}
+
/*
* Test raw (ICANON=0) input
*/
@@ -707,7 +710,7 @@ void usage( void )
rtems_task
Init (rtems_task_argument ignored)
{
- char c;
+ char c, done;
struct termios orig_termios, test_termios;
printf( "\n\n*** TEST OF TERMIOS INPUT CAPABILITIES ***\n" );
diff --git a/c/src/tests/samples/cdtest/system.h b/c/src/tests/samples/cdtest/system.h
index 557f3fea8c..d414c35451 100644
--- a/c/src/tests/samples/cdtest/system.h
+++ b/c/src/tests/samples/cdtest/system.h
@@ -34,6 +34,9 @@ rtems_task main_task(
#define CONFIGURE_INIT_TASK_ENTRY_POINT main_task
#define CONFIGURE_INIT_TASK_NAME rtems_build_name( 'C', 'T', 'O', 'R' )
+/* Guess at this one */
+#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 2
+
#include <confdefs.h>
/* end of include file */
diff --git a/c/src/tests/sptests/Makefile.am b/c/src/tests/sptests/Makefile.am
index 7452d72394..f4e22089f6 100644
--- a/c/src/tests/sptests/Makefile.am
+++ b/c/src/tests/sptests/Makefile.am
@@ -8,7 +8,7 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
## sp10 and spfatal are not included for now
SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
- spsize
+ spsize threaditerate
EXTRA_DIST = sptests.am spfatal
diff --git a/c/src/tests/sptests/configure.in b/c/src/tests/sptests/configure.in
index 0225a1fab1..47dd2200ba 100644
--- a/c/src/tests/sptests/configure.in
+++ b/c/src/tests/sptests/configure.in
@@ -67,6 +67,7 @@ sp27/Makefile
sp28/Makefile
sp29/Makefile
spsize/Makefile
+threaditerate/Makefile
)
# spfatal/Makefile
diff --git a/cpukit/libcsupport/include/sys/termios.h b/cpukit/libcsupport/include/sys/termios.h
index 7cc28d7d38..199bb2aef2 100644
--- a/cpukit/libcsupport/include/sys/termios.h
+++ b/cpukit/libcsupport/include/sys/termios.h
@@ -181,6 +181,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, struct termios *);
+int tcdrain(int);
pid_t tcgetprgrp(int);
int tcsetprgrp(int, pid_t);
int tcsendbreak(int, int);
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index 08660d75cc..dc6824891a 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -418,5 +418,27 @@ void _free_r(
{
free( ptr );
}
+
+
+/*
+ * rtems_cache_aligned_malloc
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to allocate storage that spans an
+ * integral number of cache blocks.
+ */
+RTEMS_INLINE_ROUTINE void * rtems_cache_aligned_malloc (
+ size_t nbytes
+)
+{
+ /*
+ * Arrange to have the user storage start on the first cache
+ * block beyond the header.
+ */
+ return (void *) ((((unsigned long) malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ + _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
+}
+
#endif
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index 7883e94b63..5052502e76 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
+#include <sys/filio.h>
/*
* FreeBSD does not support a full POSIX termios so we have to help it out
@@ -243,7 +244,7 @@ rtems_termios_open (
/*
* Set default parameters
*/
- tty->termios.c_iflag = BRKINT | ICRNL | IMAXBEL;
+ tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
tty->termios.c_oflag = OPOST | ONLCR | XTABS;
tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
@@ -474,6 +475,11 @@ rtems_termios_ioctl (void *arg)
case RTEMS_IO_TCDRAIN:
drainOutput (tty);
break;
+
+ case FIONREAD:
+ /* Half guess that this is the right operation */
+ *(int *)args->buffer = tty->ccount - tty->cindex;
+ break;
}
rtems_semaphore_release (tty->osem);
args->ioctl_return = sc;
diff --git a/cpukit/posix/src/waitpid.c b/cpukit/posix/src/waitpid.c
index d52177961d..e367e87074 100644
--- a/cpukit/posix/src/waitpid.c
+++ b/cpukit/posix/src/waitpid.c
@@ -1,5 +1,5 @@
/*
- * wait() - POSIX 1003.1b 3.2.1
+ * waitpid() - POSIX 1003.1 3.2.1
*
* $Id$
*/
diff --git a/cpukit/rtems/include/rtems/rtems/cache.h b/cpukit/rtems/include/rtems/rtems/cache.h
new file mode 100644
index 0000000000..1e71a9bf3a
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/cache.h
@@ -0,0 +1,140 @@
+/* cache.h
+ *
+ * Cache Manager
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ *
+ * The functions in this file define the API to the RTEMS Cache Manager and
+ * are divided into data cache and instruction cache functions. Data cache
+ * functions are only declared if a data cache is supported. Instruction
+ * cache functions are only declared if an instruction cache is supported.
+ * Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
+ * defined, where x E {DATA, INST}. These definitions are found in the CPU
+ * dependent source files in the supercore, often
+ *
+ * rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
+ *
+ * The functions below are implemented with CPU dependent inline routines
+ * also found in the above file. In the event that a CPU does not support a
+ * specific function, the CPU dependent routine does nothing (but does exist).
+ *
+ * At this point, the Cache Manager makes no considerations, and provides no
+ * support for BSP specific issues such as a secondary cache. In such a system,
+ * the CPU dependent routines would have to be modified, or a BSP layer added
+ * to this Manager.
+ */
+
+#ifndef __CACHE_h
+#define __CACHE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/system.h>
+#include <sys/types.h>
+
+
+/* THESE FUNCTIONS ONLY EXIST IF WE HAVE A DATA CACHE */
+#if defined(_CPU_DATA_CACHE_ALIGNMENT)
+
+/*
+ * This function is called to flush the data cache by performing cache
+ * copybacks. It must determine how many cache lines need to be copied
+ * back and then perform the copybacks.
+ */
+void rtems_flush_multiple_data_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache invalidate.
+ * It must determine how many cache lines need to be invalidated and then
+ * perform the invalidations.
+ */
+void rtems_invalidate_multiple_data_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing a data cache flush.
+ * It flushes the entire cache.
+ */
+void rtems_flush_entire_data_cache( void );
+
+/*
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_invalidate_entire_data_cache( void );
+
+/*
+ * This function returns the data cache granularity.
+ */
+int rtems_get_data_cache_line_size( void );
+
+/*
+ * This function freezes the data cache.
+ */
+void rtems_freeze_data_cache( void );
+
+/*
+ * This function unfreezes the data cache.
+ */
+void rtems_unfreeze_data_cache( void );
+
+/*
+ * These functions enable/disable the data cache.
+ */
+void rtems_enable_data_cache( void );
+void rtems_disable_data_cache( void );
+#endif
+
+
+/* THESE FUNCTIONS ONLY EXIST IF WE HAVE AN INSTRUCTION CACHE */
+#if defined(_CPU_INST_CACHE_ALIGNMENT)
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It must determine how many cache lines need to be invalidated
+ * and then perform the invalidations.
+ */
+void rtems_invalidate_multiple_inst_cache_lines( const void *, size_t );
+
+/*
+ * This function is responsible for performing an instruction cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_invalidate_entire_inst_cache( void );
+
+/*
+ * This function returns the instruction cache granularity.
+ */
+int rtems_get_inst_cache_line_size( void );
+
+/*
+ * This function freezes the instruction cache.
+ */
+void rtems_freeze_inst_cache( void );
+
+/*
+ * This function unfreezes the instruction cache.
+ */
+void rtems_unfreeze_inst_cache( void );
+
+/*
+ * These functions enable/disable the instruction cache.
+ */
+void rtems_enable_inst_cache( void );
+void rtems_disable_inst_cache( void );
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/rtems/src/Makefile.am b/cpukit/rtems/src/Makefile.am
index f597292be1..f2b13c2aa9 100644
--- a/cpukit/rtems/src/Makefile.am
+++ b/cpukit/rtems/src/Makefile.am
@@ -50,7 +50,7 @@ PARTITION_C_FILES = part.c partcreate.c partdelete.c partgetbuffer.c \
DPMEM_C_FILES = dpmem.c dpmemcreate.c dpmemdelete.c dpmemexternal2internal.c \
dpmemident.c dpmeminternal2external.c
-STD_C_FILES = attr.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
+STD_C_FILES = attr.c cache.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
$(CLOCK_C_FILES) $(TIMER_C_FILES) $(SEMAPHORE_C_FILES) \
$(MESSAGE_QUEUE_C_FILES) $(EVENT_C_FILES) $(SIGNAL_C_FILES) \
$(PARTITION_C_FILES) $(REGION_C_FILES) $(DPMEM_C_FILES)
diff --git a/cpukit/score/cpu/i386/rtems/score/i386.h b/cpukit/score/cpu/i386/rtems/score/i386.h
index f113ebee4e..ca1af66fff 100644
--- a/cpukit/score/cpu/i386/rtems/score/i386.h
+++ b/cpukit/score/cpu/i386/rtems/score/i386.h
@@ -144,6 +144,142 @@ static inline unsigned int i386_swap_U16(
}
+/*
+ * Added for pagination management
+ */
+
+static inline unsigned int i386_get_cr0()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr0(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
+}
+
+static inline unsigned int i386_get_cr2()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned int i386_get_cr3()
+{
+ register unsigned int segment = 0;
+
+ asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr3(unsigned int segment)
+{
+ asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
+}
+
+/*
+ * Disable the entire cache
+ */
+void _CPU_disable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 1;
+ regCr0.cr0.no_write_through = 1;
+ i386_set_cr0( regCr0.i );
+ rtems_flush_entire_data_cache();
+}
+
+/*
+ * Enable the entire cache
+ */
+static inline void _CPU_enable_cache() {
+ cr0 regCr0;
+
+ regCr0.i = i386_get_cr0();
+ regCr0.cr0.page_level_cache_disable = 0;
+ regCr0.cr0.no_write_through = 0;
+ i386_set_cr0( regCr0.i );
+ /*rtems_flush_entire_data_cache();*/
+}
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Definitions for I386_CACHE_ALIGNMENT are missing above for
+ * each CPU. The routines below should be implemented per CPU,
+ * to accomodate the capabilities of each.
+ */
+
+/* FIXME: I don't belong here. */
+#define I386_CACHE_ALIGNMENT 16
+
+#if defined(I386_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT
+
+static inline void _CPU_flush_1_data_cache_line (const void * d_addr) {}
+static inline void _CPU_invalidate_1_data_cache_line (const void * d_addr) {}
+static inline void _CPU_freeze_data_cache (void) {}
+static inline void _CPU_unfreeze_data_cache (void) {}
+static inline void _CPU_invalidate_1_inst_cache_line const void * d_addr() {}
+static inline void _CPU_freeze_inst_cache (void) {}
+static inline void _CPU_unfreeze_inst_cache (void) {}
+
+static inline void _CPU_flush_entire_data_cache (
+ const void * d_addr )
+{
+ asm ("wbinvd");
+}
+static inline void _CPU_invalidate_entire_data_cache (
+ const void * d_addr )
+{
+ asm ("invd");
+}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ _CPU_enable_cache();
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ _CPU_disable_cache();
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ const void * i_addr )
+{
+ asm ("invd");
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ _CPU_enable_cache();
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ _CPU_disable_cache();
+}
+#endif
+
+
/* routines */
/*
diff --git a/cpukit/score/cpu/m68k/rtems/score/m68k.h b/cpukit/score/cpu/m68k/rtems/score/m68k.h
index 64639220dd..c38a9a13ed 100644
--- a/cpukit/score/cpu/m68k/rtems/score/m68k.h
+++ b/cpukit/score/cpu/m68k/rtems/score/m68k.h
@@ -157,6 +157,7 @@ extern "C" {
# endif
#elif defined(__mc68302__)
+
#define CPU_MODEL_NAME "m68302"
#define M68K_HAS_VBR 0
#define M68K_HAS_SEPARATE_STACKS 0
@@ -350,16 +351,238 @@ static inline unsigned int m68k_swap_u16(
return( swapped );
}
-/* XXX this is only valid for some m68k family members and should be fixed */
+#define CPU_swap_u32( value ) m68k_swap_u32( value )
+#define CPU_swap_u16( value ) m68k_swap_u16( value )
+
+
+/*
+ * _CPU_virtual_to_physical
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to map virtual addresses to physical
+ * addresses.
+ *
+ * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
+ * PHYSICAL ADDRESSES
+ */
+static inline void * _CPU_virtual_to_physical (
+ const void * d_addr )
+{
+ return (void *) d_addr;
+}
+
+
+/*
+ * Since the cacr is common to all mc680x0, provide macros
+ * for masking values in that register.
+ */
-#define m68k_enable_caching() \
- { register unsigned32 _ctl=0x01; \
- asm volatile ( "movec %0,%%cacr" \
- : "=d" (_ctl) : "0" (_ctl) ); \
+/*
+ * Used to clear bits in the cacr.
+ */
+#define _CPU_CACR_AND(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ andl %2, %0; /* and with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
}
-#define CPU_swap_u32( value ) m68k_swap_u32( value )
-#define CPU_swap_u16( value ) m68k_swap_u16( value )
+
+/*
+ * Used to set bits in the cacr.
+ */
+#define _CPU_CACR_OR(mask) \
+ { \
+ register unsigned long _value = mask; \
+ register unsigned long _ctl = 0; \
+ asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
+ orl %2, %0; /* or with _val */ \
+ movec %1, %%cacr" /* write the cacr */ \
+ : "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
+ }
+
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ */
+#if ( defined(__mc68020__) || defined(__mc68030__) )
+#define M68K_INST_CACHE_ALIGNMENT 16
+
+#if defined(__mc68030__)
+#define M68K_DATA_CACHE_ALIGNMENT 16
+
+/* Only the mc68030 has a data cache; it is writethrough only. */
+
+static inline void _CPU_flush_1_data_cache_line ( const void * d_addr ) {}
+static inline void _CPU_flush_entire_data_cache ( const void * d_addr ) {}
+
+static inline void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR(0x00000400);
+}
+
+static inline void _CPU_invalidate_entire_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000800 );
+}
+
+static inline void _CPU_freeze_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000200 );
+}
+
+static inline void _CPU_unfreeze_data_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFFFDFF );
+}
+
+static inline void _CPU_enable_data_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000100 );
+}
+static inline void _CPU_disable_data_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFEFF );
+}
+#endif
+
+
+/* Both the 68020 and 68030 have instruction caches */
+
+static inline void _CPU_invalidate_1_inst_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
+ _CPU_CACR_OR( 0x00000004 );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000008 );
+}
+
+static inline void _CPU_freeze_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00000002);
+}
+
+static inline void _CPU_unfreeze_inst_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFD );
+}
+
+static inline void _CPU_enable_inst_cache ( void )
+{
+ _CPU_CACR_OR( 0x00000001 );
+}
+
+static inline void _CPU_disable_inst_cache ( void )
+{
+ _CPU_CACR_AND( 0xFFFFFFFE );
+}
+
+
+#elif ( defined(__mc68040__) || defined (__mc68060__) )
+
+#define M68K_INST_CACHE_ALIGNMENT 16
+#define M68K_DATA_CACHE_ALIGNMENT 16
+
+/* Cannot be frozen */
+static inline void _CPU_freeze_data_cache ( void ) {}
+static inline void _CPU_unfreeze_data_cache ( void ) {}
+static inline void _CPU_freeze_inst_cache ( void ) {}
+static inline void _CPU_unfreeze_inst_cache ( void ) {}
+
+static inline void _CPU_flush_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cpushl %%dc,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_invalidate_1_data_cache_line (
+ const void * d_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
+ asm volatile ( "cinvl %%dc,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_flush_entire_data_cache (
+ void )
+{
+ asm volatile ( "cpusha %%dc" :: );
+}
+
+static inline void _CPU_invalidate_entire_data_cache (
+ void )
+{
+ asm volatile ( "cinva %%dc" :: );
+}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x80000000 );
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ _CPU_CACR_AND( 0x7FFFFFFF );
+}
+
+static inline void _CPU_invalidate_1_inst_cache_line (
+ const void * i_addr )
+{
+ void * p_address = (void *) _CPU_virtual_to_physical( i_addr );
+ asm volatile ( "cinvl %%ic,(%0)" :: "a" (p_address) );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache (
+ void )
+{
+ asm volatile ( "cinva %%ic" :: );
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ _CPU_CACR_OR( 0x00008000 );
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ _CPU_CACR_AND( 0xFFFF7FFF );
+}
+#endif
+
+
+#if defined(M68K_DATA_CACHE_ALIGNMENT)
+#define _CPU_DATA_CACHE_ALIGNMENT M68K_DATA_CACHE_ALIGNMENT
+#endif
+
+#if defined(M68K_INST_CACHE_ALIGNMENT)
+#define _CPU_INST_CACHE_ALIGNMENT M68K_INST_CACHE_ALIGNMENT
+#endif
+
#endif /* !ASM */
@@ -367,5 +590,5 @@ static inline unsigned int m68k_swap_u16(
}
#endif
-#endif
+#endif /* __M68K_h */
/* end of include file */
diff --git a/cpukit/score/cpu/powerpc/asm.h b/cpukit/score/cpu/powerpc/asm.h
index af14c95665..3c2e28ad5c 100644
--- a/cpukit/score/cpu/powerpc/asm.h
+++ b/cpukit/score/cpu/powerpc/asm.h
@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
+#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
+#endif /* ppc403 */
+
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
+#define dar 0x013 /* Data Address Register */
+#define dec 0x016 /* Decrementer Register */
+#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
+#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
+#define ictrl 0x09E /* Instruction Support Control Register */
+#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
+#endif
/*
* Following must be tailor for a particular flavor of the C compiler.
diff --git a/cpukit/score/cpu/powerpc/rtems/asm.h b/cpukit/score/cpu/powerpc/rtems/asm.h
index af14c95665..3c2e28ad5c 100644
--- a/cpukit/score/cpu/powerpc/rtems/asm.h
+++ b/cpukit/score/cpu/powerpc/rtems/asm.h
@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
+#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
+#endif /* ppc403 */
+
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
+#define dar 0x013 /* Data Address Register */
+#define dec 0x016 /* Decrementer Register */
+#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
+#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
+#define ictrl 0x09E /* Instruction Support Control Register */
+#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
+#endif
/*
* Following must be tailor for a particular flavor of the C compiler.
diff --git a/cpukit/score/cpu/powerpc/rtems/score/ppc.h b/cpukit/score/cpu/powerpc/rtems/score/ppc.h
index 83a54bfa25..682675efde 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/ppc.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/ppc.h
@@ -44,6 +44,8 @@
extern "C" {
#endif
+#include <rtems/score/ppctypes.h>
+
/*
* Define the name of the CPU family.
*/
@@ -220,6 +222,7 @@ extern "C" {
#elif defined(mpc860)
/*
* Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
+ * with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
*/
#define CPU_MODEL_NAME "PowerPC MPC860"
@@ -231,7 +234,6 @@ extern "C" {
#define PPC_HAS_FPU 0
#define PPC_HAS_DOUBLE 0
#define PPC_USE_MULTIPLE 1
-#define PPC_USE_SPRG 1
#define PPC_MSR_0 0x00009000
#define PPC_MSR_1 0x00001000
@@ -382,6 +384,157 @@ extern "C" {
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif
+#ifndef ASM
+
+/*
+ * CACHE MANAGER: The following functions are CPU-specific.
+ * They provide the basic implementation for the rtems_* cache
+ * management routines. If a given function has no meaning for the CPU,
+ * it does nothing by default.
+ *
+ * FIXME: Some functions simply have not been implemented.
+ */
+
+#if defined(ppc603) /* And possibly others */
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+/* Helpful macros */
+#define PPC_Get_HID0( _value ) \
+ do { \
+ _value = 0; /* to avoid warnings */ \
+ asm volatile( \
+ "mfspr %0, 0x3f0;" /* get HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+#define PPC_Set_HID0( _value ) \
+ do { \
+ asm volatile( \
+ "isync;" \
+ "mtspr 0x3f0, %0;" /* load HID0 */ \
+ "isync" \
+ : "=r" (_value) \
+ : "0" (_value) \
+ ); \
+ } while (0)
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00004000; /* set DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFFBFFF; /* clear DCE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value |= 0x00008000; /* Set ICE bit */
+ PPC_Set_HID0( value );
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 value;
+ PPC_Get_HID0( value );
+ value &= 0xFFFF7FFF; /* Clear ICE bit */
+ PPC_Set_HID0( value );
+}
+
+#elif ( defined(mpc860) || defined(mpc821) )
+
+#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
+
+#define mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
+#define isync __asm__ volatile ("isync\n"::)
+
+static inline void _CPU_flush_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbf 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_1_data_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "dcbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_flush_entire_data_cache ( void ) {}
+static inline void _CPU_invalidate_entire_data_cache ( void ) {}
+static inline void _CPU_freeze_data_cache ( void ) {}
+static inline void _CPU_unfreeze_data_cache ( void ) {}
+
+static inline void _CPU_enable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_data_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 568, r1 );
+ isync;
+}
+
+static inline void _CPU_invalidate_1_inst_cache_line(
+ const void * _address )
+{
+ register const void *__address = _address;
+ asm volatile ( "icbi 0,%0" :: "r" (__address) );
+}
+
+static inline void _CPU_invalidate_entire_inst_cache ( void ) {}
+static inline void _CPU_freeze_inst_cache ( void ) {}
+static inline void _CPU_unfreeze_inst_cache ( void ) {}
+
+static inline void _CPU_enable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x2<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+
+static inline void _CPU_disable_inst_cache (
+ void )
+{
+ unsigned32 r1;
+ r1 = (0x4<<24);
+ mtspr( 560, r1 );
+ isync;
+}
+#endif
+
+#endif /* !ASM */
+
/*
* Unless otherwise specified, assume the model has an IP/EP bit to
* set the exception address prefix.
@@ -550,7 +703,7 @@ extern "C" {
#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
-#define PPC_IRQ_CPM_RESERVED_0 (PPC_STD_IRQ_LAST + 26)
+#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)
diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h
index 811e33a17e..7640dce3d3 100644
--- a/cpukit/score/include/rtems/score/object.h
+++ b/cpukit/score/include/rtems/score/object.h
@@ -444,6 +444,21 @@ Objects_Control *_Objects_Get (
);
/*
+ * _Objects_Get_by_index
+ *
+ * DESCRIPTION:
+ *
+ * This routine sets the object pointer for the given
+ * object id based on the given object information structure.
+ */
+
+Objects_Control *_Objects_Get_by_index(
+ Objects_Information *information,
+ unsigned32 index,
+ Objects_Locations *location
+);
+
+/*
* _Objects_Get_next
*
* DESCRIPTION:
@@ -460,6 +475,25 @@ Objects_Control *_Objects_Get_next(
);
/*
+ * _Objects_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing object
+ * of the type specified by the information block pointer. Iteration
+ * continues until either all objects have been processed, or, if
+ * break_on_error is TRUE, until an invocation of the callback returns
+ * something other than 0.
+ */
+
+unsigned32 _Objects_Local_iterate(
+ Objects_Information *information,
+ unsigned32 (*callback)(Objects_Control *object, void * arg),
+ void * arg,
+ boolean break_on_error
+);
+
+/*
* Pieces of object.inl are promoted out to the user
*/
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 4c8032f558..7739925e66 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -734,6 +734,23 @@ Thread_Control *_Thread_Get (
#endif
/*
+ * _Thread_Local_iterate
+ *
+ * DESCRIPTION:
+ *
+ * This function invokes the callback function for each existing thread.
+ * Iteration continues until either all threads have been processed, or,
+ * if break_on_error is TRUE, until an invocation of the callback returns
+ * an integer value other than 0.
+ */
+
+unsigned32 _Thread_Local_iterate(
+ unsigned32 (*callback)(Thread_Control *the_thread, void * arg),
+ void * arg,
+ boolean break_on_error
+);
+
+/*
* _Thread_Idle_body
*
* DESCRIPTION:
diff --git a/cpukit/score/src/Makefile.am b/cpukit/score/src/Makefile.am
index c348a606f1..97a2597cda 100644
--- a/cpukit/score/src/Makefile.am
+++ b/cpukit/score/src/Makefile.am
@@ -27,17 +27,18 @@ OBJECT_C_FILES = object.c objectallocate.c objectallocatebyindex.c \
objectclearname.c objectcomparenameraw.c objectcomparenamestring.c \
objectcopynameraw.c objectcopynamestring.c objectextendinformation.c \
objectfree.c objectget.c objectgetbyindex.c objectgetnext.c \
- objectinitializeinformation.c objectnametoid.c objectshrinkinformation.c
+ objectinitializeinformation.c objectlocaliterate.c objectnametoid.c \
+ objectshrinkinformation.c
THREAD_C_FILES = thread.c threadchangepriority.c threadclearstate.c \
threadclose.c threadcreateidle.c threaddelayended.c threaddispatch.c \
threadevaluatemode.c threadget.c threadhandler.c threadidlebody.c \
- threadinitialize.c threadloadenv.c threadready.c threadresettimeslice.c \
- threadreset.c threadrestart.c threadresume.c threadrotatequeue.c \
- threadsetpriority.c threadsetstate.c threadsettransient.c \
- threadstackallocate.c threadstackfree.c threadstart.c \
- threadstartmultitasking.c threadsuspend.c threadtickletimeslice.c \
- threadyieldprocessor.c
+ threadinitialize.c threadloadenv.c threadlocaliterate.c threadready.c \
+ threadresettimeslice.c threadreset.c threadrestart.c threadresume.c \
+ threadrotatequeue.c threadsetpriority.c threadsetstate.c \
+ threadsettransient.c threadstackallocate.c threadstackfree.c \
+ threadstart.c threadstartmultitasking.c threadsuspend.c \
+ threadtickletimeslice.c threadyieldprocessor.c
THREADQ_C_FILES = threadq.c threadqdequeue.c threadqdequeuefifo.c \
threadqdequeuepriority.c threadqenqueue.c threadqenqueuefifo.c \
@@ -53,8 +54,8 @@ WATCHDOG_C_FILES = watchdog.c watchdogadjust.c watchdoginsert.c \
watchdogremove.c watchdogtickle.c
STD_C_FILES = apiext.c chain.c $(CORE_MESSAGE_QUEUE_C_FILES) \
- $(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) interr.c \
- isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
+ $(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) \
+ interr.c isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
$(TOD_C_FILES) userext.c $(WATCHDOG_C_FILES) wkspace.c
if HAS_MP
diff --git a/make/compilers/gcc-target-default.cfg b/make/compilers/gcc-target-default.cfg
index fb5dfbad62..c0baabb6d4 100644
--- a/make/compilers/gcc-target-default.cfg
+++ b/make/compilers/gcc-target-default.cfg
@@ -88,17 +88,26 @@ endif
# debug flag;
CFLAGS_DEBUG_V+=-Wno-unused
+CXXFLAGS_DEBUG_V+=
ifeq ($(RTEMS_USE_GCC272),no)
CFLAGS_DEBUG_V+=-qrtems_debug
+CXXFLAGS_DEBUG_V+=-qrtems_debug
endif
+# when debugging, optimize flag: typically empty
+# some compilers do allow optimization with their "-g"
+CFLAGS_DEBUG_OPTIMIZE_V=-g
+CXXFLAGS_DEBUG_OPTIMIZE_V=-g
+
# profile flag; use gprof(1)
CFLAGS_PROFILE_V=-pg
+CXXFLAGS_PROFILE_V=-pg
ifndef AUTOMAKE
# default is to optimize
-CFLAGS_OPTIMIZE=$(CFLAGS_OPTIMIZE_V)
+CFLAGS_OPTIMIZE =$(CFLAGS_OPTIMIZE_V)
+CXXFLAGS_OPTIMIZE=$(CXXFLAGS_OPTIMIZE_V)
endif
# dynamic libraries
@@ -106,7 +115,8 @@ endif
#ASFLAGS_DYNAMIC_V=
ifndef AUTOMAKE
-CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
+CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
+CXXFLAGS += $(CXXFLAGS_OPTIMIZE) $(CXXFLAGS_DEBUG) $(CXXFLAGS_PROFILE)
endif
# List of library paths without -L
diff --git a/make/custom/eth_comm.cfg b/make/custom/eth_comm.cfg
index cde4b4ee30..901decbb77 100644
--- a/make/custom/eth_comm.cfg
+++ b/make/custom/eth_comm.cfg
@@ -7,7 +7,8 @@
include $(RTEMS_ROOT)/make/custom/default.cfg
RTEMS_CPU=powerpc
-RTEMS_CPU_MODEL=mpc860
+RTEMS_CPU_MODEL=mpc8xx
+CPU_TYPE=860
# This is the actual bsp directory used during the build process.
RTEMS_BSP_FAMILY=eth_comm
@@ -25,17 +26,45 @@ CPU_DEFINES=-DPPC_VECTOR_FILE_BASE=0x00000000
#
# RTEMS_DEBUG (RTEMS)
# If defined, debug checks in RTEMS and support library code are enabled.
+#
+# PPC_VECTOR_FILE_BASE (PowerPC)
+# This defines the base address of the exception table.
+# NOTE: Vectors are actually at 0xFFF00000 but file starts at offset 0x0100
+#
+# PPC_ABI (PowerPC)
+# This defines the calling convention (Application Binary Interface)
+# used in this configuration. EABI is the only one supported.
+# This BSP was initially developed using the PowerOpen ABI.
+#
+# PPC_ASM (PowerPC)
+# This defines the assembly language format used in this configuration.
+# ELF is the only one supported.
+#
+# PPC_USE_SPRG (RTEMS PowerPC port)
+# If defined (=1), then the PowerPC specific code in RTEMS will use some
+# of the special purpose registers to slightly optimize interrupt
+# response time. The use of these registers can conflict with
+# other tools like debuggers.
define make-target-options
+ @echo "#ifdef mpc$(CPU_TYPE)" >>$@
+ @echo "#undef mpc$(CPU_TYPE)" >>$@
+ @echo "#endif" >>$@
+ @echo "#define mpc$(CPU_TYPE) 1" >>$@
+ @echo >>$@
@echo "/* #define NDEBUG 1 */ " >>$@
@echo "#define RTEMS_TEST_NO_PAUSE 1" >>$@
@echo "/* #define RTEMS_DEBUG 1 */" >>$@
+ @echo "#define PPC_VECTOR_FILE_BASE 0x0000" >>$@
+ @echo "#define PPC_ABI PPC_ABI_EABI" >>$@
+ @echo "#define PPC_ASM PPC_ASM_ELF" >>$@
+ @echo "#define PPC_USE_SPRG 1" >>$@
endef
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
#
-CPU_CFLAGS = -mcpu=860
+CPU_CFLAGS = -mcpu=$(CPU_TYPE)
# optimize flag: typically -0, could use -O4 or -fast
# -O4 is ok for RTEMS
diff --git a/make/custom/mvme167.cfg b/make/custom/mvme167.cfg
index df47822c73..ade3c6f68f 100644
--- a/make/custom/mvme167.cfg
+++ b/make/custom/mvme167.cfg
@@ -86,14 +86,15 @@ ifeq ($(RTEMS_USE_GCC272),yes)
define make-exe
$(LD) $(LDFLAGS) -N -T $(LINKCMDS) -o $(basename $@).exe \
$(START_FILE) $(LINK_OBJS) --start-group $(LINK_LIBS) --end-group
- $(NM) -g -n $(basename $@).exe > $(basename $@).num
+ $(NM) -g -n $(basename $@).exe > $(basename $@).nm
+ $(STRIP) -o $(basename $@) $@
$(SIZE) $(basename $@).exe
endef
else
define make-exe
$(LINK.c) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ \
$(LINK_OBJS) $(LINK_LIBS)
- $(NM) -g -n $@ > $(basename $@).nm
+ $(NM) -g -n $(basename $@).exe > $(basename $@).nm
$(STRIP) -o $(basename $@) $@
$(SIZE) $(basename $@).exe
endef
diff --git a/make/leaf.cfg b/make/leaf.cfg
index a4f29aa6ef..a1e3e1b1f3 100644
--- a/make/leaf.cfg
+++ b/make/leaf.cfg
@@ -49,13 +49,15 @@ ifndef AUTOMAKE
debug:
$(MAKE) -f $(MAKEFILE) MAKEFILE=$(MAKEFILE) "ARCH=o-debug" \
"CFLAGS_DEBUG=$(CFLAGS_DEBUG_V)" \
- "CFLAGS_OPTIMIZE=$(CFLAGS_OPTIMIZE_V)" \
+ "CXXFLAGS_DEBUG=$(CXXFLAGS_DEBUG_V)" \
+ "CFLAGS_OPTIMIZE=$(CFLAGS_DEBUG_OPTIMIZE_V)" \
"LDFLAGS_DEBUG=$(LDFLAGS_DEBUG_V)" $(TARGET_VA)
profile:
$(MAKE) -f $(MAKEFILE) \
MAKEFILE=$(MAKEFILE) "ARCH=o-profile" \
"CFLAGS_PROFILE=$(CFLAGS_PROFILE_V)" \
+ "CXXFLAGS_PROFILE=$(CXXFLAGS_PROFILE_V)" \
"LDFLAGS_PROFILE=$(LDFLAGS_PROFILE_V)" $(TARGET_VA)
endif
diff --git a/testsuites/libtests/termios/init.c b/testsuites/libtests/termios/init.c
index bc4097a8cc..37e6506eea 100644
--- a/testsuites/libtests/termios/init.c
+++ b/testsuites/libtests/termios/init.c
@@ -24,6 +24,7 @@
#include <bsp.h>
+
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
@@ -587,6 +588,7 @@ void change_line_settings( struct termios *tp )
void canonical_input( struct termios *tp )
{
+ char buffer[256];
char c, first_time = TRUE;
printf( "\nTesting canonical input\n\n" );
@@ -612,6 +614,7 @@ void canonical_input( struct termios *tp )
printf( "\n\nCanonical input test done.\n" );
}
+
/*
* Test raw (ICANON=0) input
*/
@@ -707,7 +710,7 @@ void usage( void )
rtems_task
Init (rtems_task_argument ignored)
{
- char c;
+ char c, done;
struct termios orig_termios, test_termios;
printf( "\n\n*** TEST OF TERMIOS INPUT CAPABILITIES ***\n" );
diff --git a/testsuites/samples/cdtest/system.h b/testsuites/samples/cdtest/system.h
index 557f3fea8c..d414c35451 100644
--- a/testsuites/samples/cdtest/system.h
+++ b/testsuites/samples/cdtest/system.h
@@ -34,6 +34,9 @@ rtems_task main_task(
#define CONFIGURE_INIT_TASK_ENTRY_POINT main_task
#define CONFIGURE_INIT_TASK_NAME rtems_build_name( 'C', 'T', 'O', 'R' )
+/* Guess at this one */
+#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 2
+
#include <confdefs.h>
/* end of include file */
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 7452d72394..f4e22089f6 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -8,7 +8,7 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
## sp10 and spfatal are not included for now
SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
- spsize
+ spsize threaditerate
EXTRA_DIST = sptests.am spfatal