summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc5xx
diff options
context:
space:
mode:
authorRalf Corsepius <ralf.corsepius@rtems.org>2004-03-08 15:36:03 +0000
committerRalf Corsepius <ralf.corsepius@rtems.org>2004-03-08 15:36:03 +0000
commit0aee2be50e93ea3e719102e6f0e59d8364f8ba0c (patch)
treef16e0ae9765416f62e4f512b10cad61d57cf2c02 /c/src/lib/libcpu/powerpc/mpc5xx
parentUnused (diff)
downloadrtems-0aee2be50e93ea3e719102e6f0e59d8364f8ba0c.tar.bz2
2004-03-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* mpc5xx/.cvsignore, mpc5xx/Makefile.am: New. * mpc5xx/exceptions/asm_utils.S, mpc5xx/exceptions/raw_exception.c, mpc5xx/exceptions/raw_exception.h, mpc5xx/ictrl/ictrl.c, mpc5xx/ictrl/ictrl.h, mpc5xx/timer/timer.c: New (Submission from Wilfried Busalski <w.busalski@lancier-monitoring.de>).
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc5xx')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/.cvsignore2
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am91
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S64
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c205
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h190
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c68
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.h75
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c70
8 files changed, 765 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/.cvsignore b/c/src/lib/libcpu/powerpc/mpc5xx/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am b/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am
new file mode 100644
index 0000000000..582a354de6
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am
@@ -0,0 +1,91 @@
+##
+## Makefile.am,v 1.4 2002/03/28 00:48:14 joel Exp
+##
+
+CLEANFILES =
+EXTRA_DIST =
+EXTRA_PROGRAMS =
+noinst_DATA =
+
+include $(top_srcdir)/../../../automake/compile.am
+
+if mpc5xx
+include_libcpudir = $(includedir)/libcpu
+
+# exceptions
+include_libcpu_HEADERS = exceptions/raw_exception.h
+
+EXTRA_PROGRAMS += exceptions.rel
+CLEANFILES += exceptions.rel
+exceptions_rel_SOURCES = exceptions/raw_exception.c exceptions/asm_utils.S
+exceptions_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+exceptions_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += exceptions_g.rel
+CLEANFILES += exceptions_g.rel
+exceptions_g_rel_SOURCES = $(exceptions_rel_SOURCES)
+exceptions_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+exceptions_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += exceptions$(LIB_VARIANT).rel
+
+# ictrl
+include_HEADERS = ictrl/ictrl.h
+
+EXTRA_PROGRAMS += ictrl.rel
+CLEANFILES += ictrl.rel
+ictrl_rel_SOURCES = ictrl/ictrl.c ictrl/ictrl.h
+ictrl_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+ictrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += ictrl_g.rel
+CLEANFILES += ictrl_g.rel
+ictrl_g_rel_SOURCES = $(ictrl_rel_SOURCES)
+ictrl_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+ictrl_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += ictrl$(LIB_VARIANT).rel
+
+# timer
+EXTRA_PROGRAMS += timer.rel
+CLEANFILES += timer.rel
+timer_rel_SOURCES = timer/timer.c
+timer_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += timer_g.rel
+CLEANFILES += timer_g.rel
+timer_g_rel_SOURCES = $(timer_rel_SOURCES)
+timer_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+timer_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += timer$(LIB_VARIANT).rel
+endif
+
+PREINSTALL_DIRS =
+PREINSTALL_FILES =
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+if mpc5xx
+$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/libcpu
+ @: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+
+$(PROJECT_INCLUDE)/libcpu/raw_exception.h: exceptions/raw_exception.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/raw_exception.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/raw_exception.h
+
+$(PROJECT_INCLUDE)/ictrl.h: ictrl/ictrl.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ictrl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ictrl.h
+endif
+
+CLEANFILES += $(PREINSTALL_FILES)
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+
+include $(top_srcdir)/../../../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S
new file mode 100644
index 0000000000..ae0e1010b5
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S
@@ -0,0 +1,64 @@
+/*
+ * asm_utils.s
+ *
+ * asm_utils.S,v 1.2 2002/04/18 20:55:37 joel Exp
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ *
+ * This file contains the low-level support for moving exception
+ * exception code to appropriate location.
+ *
+ * Adapted for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
+ * (C) Lancier Monitoring GmbH
+ */
+
+#include <asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/io.h>
+
+//SPR defines
+#define SPR_ICCST 560
+
+
+ .globl codemove
+codemove:
+ .type codemove,@function
+/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
+ cmplw cr1,r3,r4
+ addi r0,r5,3
+ srwi. r0,r0,2
+ beq cr1,4f /* In place copy is not necessary */
+ beq 7f /* Protect against 0 count */
+ mtctr r0
+ bge cr1,2f
+
+ la r8,-4(r4)
+ la r7,-4(r3)
+1: lwzu r0,4(r8)
+ stwu r0,4(r7)
+ bdnz 1b
+ b 4f
+
+2: slwi r0,r0,2
+ add r8,r4,r0
+ add r7,r3,r0
+3: lwzu r0,-4(r8)
+ stwu r0,-4(r7)
+ bdnz 3b
+
+/* Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+
+4: lis r0, 0x0A00 // Command Unlock All
+ mtspr SPR_ICCST, r0 // Cache Unlock ALL
+
+ lis r0, 0x0C00 // Command Invalidate All
+ mtspr SPR_ICCST, r0 // Cache Invalidate ALL
+
+ lis r0, 0x0200 // Command Enable All
+ mtspr SPR_ICCST, r0 // Cache Enable ALL
+
+7: sync /* Wait for all icbi to complete on bus */
+ isync
+ blr
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c
new file mode 100644
index 0000000000..649ec0b956
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c
@@ -0,0 +1,205 @@
+/*
+ * raw_exception.c - This file contains implementation of C function to
+ * Instanciate 8xx ppc primary exception entries.
+ * More detailled information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC860
+ * Risc Microporcessor User's Manual
+ * Motorola REF : MPC860UM/AD
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * Changes for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
+ * Copyright (C) 2003 Lancier Monitoring GmbH
+ *
+ * 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.
+ *
+ * raw_exception.c,v 1.5 2002/11/04 14:29:02 joel Exp
+ */
+
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/ppc.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/cpuIdent.h>
+#include <rtems/bspIo.h> /* for printk */
+#include <string.h>
+
+void * codemove(void *, const void *, unsigned int, unsigned long);
+
+static rtems_raw_except_connect_data* raw_except_table;
+static rtems_raw_except_connect_data default_raw_except_entry;
+static rtems_raw_except_global_settings* local_settings;
+
+int mpc565_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_FLOATASSIST_VECTOR:
+
+ case ASM_SOFTEMUL_VECTOR:
+
+ case ASM_ITLBERROR_VECTOR:
+ case ASM_DTLBERROR_VECTOR:
+
+ case ASM_DBREAK_VECTOR:
+ case ASM_IBREAK_VECTOR:
+ case ASM_PERIFBREAK_VECTOR:
+ case ASM_DEVPORT_VECTOR:
+ return 1;
+ default: return 0;
+ }
+}
+
+int mpc5xx_vector_is_valid(rtems_vector vector)
+{
+ switch (current_ppc_cpu) {
+ case MPC_5XX:
+ if (!mpc565_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+ default:
+ printk("Please complete libcpu/powerpc/mpc5xx/exceptions/raw_exception.c\n");
+ printk("current_ppc_cpu = %x\n", current_ppc_cpu);
+ return 0;
+ }
+ return 1;
+}
+
+int mpc5xx_set_exception (const rtems_raw_except_connect_data* except)
+{
+ unsigned int level;
+
+ if (!mpc5xx_vector_is_valid(except->exceptIndex)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via mpc5xx_get_current_exception
+ * and then disconnect it using mpc5xx_delete_exception.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (memcmp(mpc5xx_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) {
+ return 0;
+ }
+
+ _CPU_ISR_Disable(level);
+
+ raw_except_table [except->exceptIndex] = *except;
+ codemove((void*)mpc5xx_get_vector_addr(except->exceptIndex),
+ except->hdl.raw_hdl,
+ except->hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+ except->on(except);
+
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int mpc5xx_get_current_exception (rtems_raw_except_connect_data* except)
+{
+ if (!mpc5xx_vector_is_valid(except->exceptIndex)){
+ return 0;
+ }
+
+ *except = raw_except_table [except->exceptIndex];
+
+ return 1;
+}
+
+int mpc5xx_delete_exception (const rtems_raw_except_connect_data* except)
+{
+ unsigned int level;
+
+ if (!mpc5xx_vector_is_valid(except->exceptIndex)){
+ return 0;
+ }
+ /*
+ * Check if handler passed is actually connected. If not issue an error.
+ * You must first get the current handler via mpc5xx_get_current_exception
+ * and then disconnect it using mpc5xx_delete_exception.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (memcmp(mpc5xx_get_vector_addr(except->exceptIndex),
+ (void*)except->hdl.raw_hdl,
+ except->hdl.raw_hdl_size)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+
+ except->off(except);
+ codemove((void*)mpc5xx_get_vector_addr(except->exceptIndex),
+ default_raw_except_entry.hdl.raw_hdl,
+ default_raw_except_entry.hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+
+
+ raw_except_table[except->exceptIndex] = default_raw_except_entry;
+ raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * Exception global init.
+ */
+int mpc5xx_init_exceptions (rtems_raw_except_global_settings* config)
+{
+ unsigned i;
+ unsigned int level;
+
+ /*
+ * store various accelerators
+ */
+ raw_except_table = config->rawExceptHdlTbl;
+ local_settings = config;
+ default_raw_except_entry = config->defaultRawEntry;
+
+ _CPU_ISR_Disable(level);
+
+ for (i=0; i <= LAST_VALID_EXC; i++) {
+ if (!mpc5xx_vector_is_valid(i)){
+ continue;
+ }
+ codemove((void*)mpc5xx_get_vector_addr(i),
+ raw_except_table[i].hdl.raw_hdl,
+ raw_except_table[i].hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+ if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
+ raw_except_table[i].on(&raw_except_table[i]);
+ }
+ else {
+ raw_except_table[i].off(&raw_except_table[i]);
+ }
+ }
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+int mpc5xx_get_exception_config (rtems_raw_except_global_settings** config)
+{
+ *config = local_settings;
+ return 1;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h
new file mode 100644
index 0000000000..515a84a201
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h
@@ -0,0 +1,190 @@
+/*
+ * raw_execption.h
+ *
+ * This file contains implementation of C function to
+ * Instanciate 8xx ppc primary exception entries.
+ * More detailled information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC860
+ * Risc Microporcessor User's Manual
+ * Motorola REF : MPC860UM/AD 07/98 Rev .1
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * Changes for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
+ * Copyright (C) 2003 Lancier Monitoring GmbH
+
+ *
+ * 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.
+ *
+ * raw_exception.h,v 1.1 2001/04/06 15:54:18 joel Exp
+ */
+
+#ifndef _LIBCPU_MPC5XX_EXCEPTION_RAW_EXCEPTION_H
+#define _LIBCPU_MPC5XX_EXCEPTION_RAW_EXCEPTION_H
+
+/*
+ * Exception Vectors as defined in the MCP750 manual
+ */
+
+#define ASM_RESET_VECTOR 0x01
+#define ASM_MACH_VECTOR 0x02
+#define ASM_PROT_VECTOR 0x03
+#define ASM_ISI_VECTOR 0x04
+#define ASM_EXT_VECTOR 0x05
+#define ASM_ALIGN_VECTOR 0x06
+#define ASM_PROG_VECTOR 0x07
+#define ASM_FLOAT_VECTOR 0x08
+#define ASM_DEC_VECTOR 0x09
+
+#define ASM_SYS_VECTOR 0x0C
+#define ASM_TRACE_VECTOR 0x0D
+#define ASM_FLOATASSIST_VECTOR 0x0E
+
+#define ASM_SOFTEMUL_VECTOR 0x10
+
+#define ASM_ITLBERROR_VECTOR 0x13
+#define ASM_DTLBERROR_VECTOR 0x14
+
+#define ASM_DBREAK_VECTOR 0x1C
+#define ASM_IBREAK_VECTOR 0x1D
+#define ASM_PERIFBREAK_VECTOR 0x1E
+#define ASM_DEVPORT_VECTOR 0x1F
+
+#define LAST_VALID_EXC ASM_DEVPORT_VECTOR
+
+/*
+ * Vector offsets as defined in the MPC860 manual
+ */
+
+#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8)
+#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8)
+#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8)
+#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8)
+#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8)
+#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8)
+#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8)
+#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8)
+#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8)
+
+#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8)
+#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8)
+#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8)
+
+#define ASM_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8)
+
+#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8)
+#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8)
+
+#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8)
+#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
+#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8)
+#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 8)
+
+#ifndef ASM
+
+/*
+ * Type definition for raw exceptions.
+ */
+
+typedef unsigned char rtems_vector;
+struct __rtems_raw_except_connect_data__;
+typedef void (*rtems_raw_except_func) (void);
+typedef unsigned char rtems_raw_except_hdl_size;
+
+typedef struct {
+ rtems_vector vector;
+ rtems_raw_except_func raw_hdl;
+ rtems_raw_except_hdl_size raw_hdl_size;
+}rtems_raw_except_hdl;
+
+typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*);
+typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*);
+typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*);
+
+typedef struct __rtems_raw_except_connect_data__{
+ /*
+ * Exception vector (As defined in the manual)
+ */
+ rtems_vector exceptIndex;
+ /*
+ * Exception raw handler. See comment on handler properties below in function prototype.
+ */
+ rtems_raw_except_hdl hdl;
+ /*
+ * function for enabling raw exceptions. In order to be consistent
+ * with the fact that the raw connexion can defined in the
+ * libcpu library, this library should have no knowledge of
+ * board specific hardware to manage exceptions and thus the
+ * "on" routine must enable the except at processor level only.
+ *
+ */
+ rtems_raw_except_enable on;
+ /*
+ * function for disabling raw exceptions. In order to be consistent
+ * with the fact that the raw connexion can defined in the
+ * libcpu library, this library should have no knowledge of
+ * board specific hardware to manage exceptions and thus the
+ * "on" routine must disable the except both at device and PIC level.
+ *
+ */
+ rtems_raw_except_disable off;
+ /*
+ * function enabling to know what exception may currently occur
+ */
+ rtems_raw_except_is_enabled isOn;
+}rtems_raw_except_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int exceptSize;
+ /*
+ * Default handler used when disconnecting exceptions.
+ */
+ rtems_raw_except_connect_data defaultRawEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_raw_except_connect_data* rawExceptHdlTbl;
+}rtems_raw_except_global_settings;
+
+/*
+ * C callable function enabling to set up one raw idt entry
+ */
+extern int mpc5xx_set_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to get one current raw idt entry
+ */
+extern int mpc5xx_get_current_exception (rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to remove one current raw idt entry
+ */
+extern int mpc5xx_delete_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to check if vector is valid
+ */
+extern int mpc5xx_vector_is_valid(rtems_vector vector);
+
+inline static void* mpc5xx_get_vector_addr(rtems_vector vector)
+{
+ return ((void*) (((unsigned) vector) << 8));
+}
+/*
+ * Exception global init.
+ */
+extern int mpc5xx_init_exceptions (rtems_raw_except_global_settings* config);
+extern int mpc5xx_get_exception_config (rtems_raw_except_global_settings** config);
+
+# endif /* ASM */
+
+#endif
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
new file mode 100644
index 0000000000..9590e5ba1a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
@@ -0,0 +1,68 @@
+/*
+ * mpc505/509 external interrupt controller management.
+ */
+
+#include "ictrl.h"
+
+#include <rtems.h>
+#include <rtems/score/ppc.h>
+
+/*
+ * Internal routines.
+ */
+
+static unsigned long volatile *const IRQAND =
+ (unsigned long volatile *const)0x8007EFA4;
+
+static void nullHandler()
+{
+}
+
+/* Interrupt dispatch table. */
+static ExtIsrHandler extIrqHandlers[NUM_IRQS] =
+{
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler
+};
+
+
+/* RTEMS external interrupt handler. Calls installed external interrupt
+ handlers for every pending external interrupt in turn. */
+static rtems_isr extIsr_( rtems_vector_number i )
+{
+#define BIT_NUMBER(val, bit) \
+ asm volatile ( "cntlzw %0, %1; srawi %0, %0, 1": "=r" (bit) : "r" (val) );
+
+ int bit;
+ (void)i;
+
+ BIT_NUMBER(*IRQAND & IMASK_ALL, bit);
+ while ( bit < NUM_IRQS ) {
+ extIrqHandlers[bit]();
+ BIT_NUMBER(*IRQAND & IMASK_ALL, bit);
+ }
+}
+
+/*
+ * Public routines
+ */
+
+void extIrqSetHandler(ExtInt interrupt,ExtIsrHandler handler)
+{
+ extIrqHandlers[interrupt] = handler;
+}
+
+void extIsrInit( void )
+{
+ int i = 0;
+
+ extIrqDisable(IMASK_ALL);
+ for( i = 0; i < NUM_IRQS; i++)
+ extIrqHandlers[i] = nullHandler;
+ set_vector(extIsr_,PPC_IRQ_EXTERNAL,1);
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.h b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.h
new file mode 100644
index 0000000000..303ece825d
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.h
@@ -0,0 +1,75 @@
+#ifndef _ICTRL_H
+#define _ICTRL_H
+
+/*
+ * mpc505/509 external interrupt controller management.
+ *
+ * FIXME: should be somehow merged into general RTEMS interrupt
+ * management code.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _SIU_IRQENABLE ((unsigned long volatile *const)0x8007EFA8)
+#define _SIU_IRQPEND ((unsigned long volatile *const)0x8007EFA0)
+
+/* Interrupt masks. */
+enum {
+ IMASK_EXT0 = 0x80000000,
+ IMASK_EXT1 = 0x20000000,
+ IMASK_EXT2 = 0x08000000,
+ IMASK_EXT3 = 0x02000000,
+ IMASK_EXT4 = 0x00800000,
+ IMASK_EXT5 = 0x00200000,
+ IMASK_EXT6 = 0x00080000,
+ IMASK_ALL = IMASK_EXT0 | IMASK_EXT1 | IMASK_EXT2 | IMASK_EXT3 |
+ IMASK_EXT4 | IMASK_EXT5 | IMASK_EXT6
+};
+
+/* Interrupt numbers. */
+typedef enum {
+ IRQ_EXT0,
+ IRQ_EXT1,
+ IRQ_EXT2,
+ IRQ_EXT3,
+ IRQ_EXT4,
+ IRQ_EXT5,
+ IRQ_EXT6,
+ NUM_IRQS
+} ExtInt;
+
+/* Type of external interrupt handlers */
+typedef void (*ExtIsrHandler) (void);
+
+/* Initialization. Must be called once after RTEMS interrupts sybsystem
+ is initiailized. 'predriver_hook' is one of such places. */
+extern void extIsrInit( void );
+
+/* Set interrupt handler 'handler' for external interrupt number
+ 'interrupt'. */
+extern void extIrqSetHandler(ExtInt interrupt, ExtIsrHandler handler);
+
+/* Check is external interrupt 'irq' (IMASK_XXXX) is pended. */
+#define extIrqIsSet(irq) \
+ (*_SIU_IRQPEND & (irq))
+
+/* Enable external interrupt 'irq' (IMASK_XXXX) processing. */
+#define extIrqEnable(irq) \
+ (*_SIU_IRQENABLE |= (irq))
+
+/* Disable external interrupt 'irq' (IMASK_XXXX) processing. */
+#define extIrqDisable(irq) \
+ (*_SIU_IRQENABLE &= ~(irq))
+
+/* Check if external interrupt 'irq' (IMASK_XXXX) processing is
+ enabled. */
+#define extIrqGetEnable \
+ (*_SIU_IRQENABLE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ICTRL_H */
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c b/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c
new file mode 100644
index 0000000000..f7741dcfe3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c
@@ -0,0 +1,70 @@
+/* timer.c
+ *
+ * This file manages the benchmark timer used by the RTEMS Timing Test
+ * Suite. Each measured time period is demarcated by calls to
+ * Timer_initialize() and Read_timer(). Read_timer() usually returns
+ * the number of microseconds since Timer_initialize() exitted.
+ *
+ * NOTE: It is important that the timer start/stop overhead be
+ * determined when porting or modifying this code.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * timer.c,v 1.2 1995/05/31 16:56:39 joel Exp
+ */
+
+#include <rtems.h>
+
+rtems_boolean Timer_driver_Find_average_overhead;
+
+static unsigned int volatile lastInitValue;
+
+void Timer_initialize( void )
+{
+ asm volatile( " mftb %0": "=r" (lastInitValue) );
+}
+
+/*
+ * The following controls the behavior of Read_timer().
+ *
+ * AVG_OVEREHAD is the overhead for starting and stopping the timer. It
+ * is usually deducted from the number returned.
+ *
+ * LEAST_VALID is the lowest number this routine should trust. Numbers
+ * below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */
+ /* (Y countdowns) to start/stop the timer. */
+ /* This value is in microseconds. */
+#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
+
+int Read_timer( void )
+{
+ rtems_unsigned32 value;
+ asm volatile ( " mftb %0": "=r" (value) );
+ return value - lastInitValue;
+}
+
+/*
+ * Empty function call used in loops to measure basic cost of looping
+ * in Timing Test Suite.
+ */
+
+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;
+}