summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/ppc403/ictrl
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-09-30 21:55:53 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-09-30 21:55:53 +0000
commitaecfa2bf09e26bfef4cb07bfe31d94ab0c92ae1a (patch)
tree364d49eba07d2be2cc1455ab7f2dafcc261f706f /c/src/lib/libcpu/powerpc/ppc403/ictrl
parentBSP submitted by Thomas Doerfler <td@imd.m.isar.de>: (diff)
downloadrtems-aecfa2bf09e26bfef4cb07bfe31d94ab0c92ae1a.tar.bz2
BSP submitted by Thomas Doerfler <td@imd.m.isar.de>:
Finally I am through: I have found the last bugs that made RTEMS- 4.0-beta3 start on my ppc403 board from ROM. So now the '403 support is up to date again. Roughly I have added the following features: - support for the on-chip interrupt controller (in a separate module) - interrupt support for the console device - termios support for the console device ============================================== Since the BSP behaivour changed in some details (console no longer is polling, other memory layout etc) I have created a new BSP "helas403" rather than changing the "papyrus" BSP. The old "polled" console driver still sticks around in "console.c.polled" To get the BSP up and running, I had to create the new BSP files (derived from papyrus). Besides that, the following source areas have been changed: - c/src/lib/libcpu/powerpc/ppc403: changes to console driver, small changes to clock driver, new "ictrl" interrupt controller driver - c/src/exec/score/cpu/powerpc/ppc.h: some small changes (added ppc403 characteristics like a exception vector prefix register, some special register definitions). I am quite sure, they are compatible with the existing sources, although I did not check - c/src/exec/score/cpu/powerpc/cpu.c: There is one severe limitation in the exception entries: Due to the current code arrangement, the "branch absolute" to the ISR handler may only jump to the first 128MByte or the last 128MByte of the 4GByte address range. When the ppc403 is running out of ROM, the ROM functions are located in the last 128MByte (0xFFF00000 and up). These addresses were not handled correctly (sign reduced) in "install_raw_handler". The change I added should work on existing ppc BSPs aswell... - c/src/lib/libc/termios.c: During my tests, I added one change you sent me, so this patch will already be incorporated in the current source tree. There are some smaller changes, see the attached diff file. ========================================= Concerning the GNU toolchain: I tried several tool chains. Finally I almost succeeded with egcs-1.0.3a with patch egcs-1.0.3-rtems-diff-19980527 I had to add the following lines to the egcs files. Without them configure complaint that the cross compiler could not generate executable output. - additional lines needed in egcs distribution in file gcc/config/rs6000/rtems.h: +++ lines start #undef STARTFILE_DEFAULT_SPEC #define STARTFILE_DEFAULT_SPEC "ecrti.o%s" #undef ENDFILE_DEFAULT_SPEC #define ENDFILE_DEFAULT_SPEC "ecrtn.o%s" ++++ lines end As far as I have seen in the Changelog of egcs, you have recently sent two patches affecting the powerpc support, but they were added in the wrong order.... :-( egcs-19980628 with patch egcs-19980628-rtems-diff-19980707 does not work! I used binutils 2.9.1 with patch binutils-2.9.1-rtems-diff-19980515 (binutils 2.8.1 does not work, internal error in gas) and newlib-1.8.0 with patch newlib-1.8.0-rtems-diff-19980707 Finally I had to poke a line in the "bit" script, since, on my LINUX machine, the GNU make is only available as "make", not as "gmake"... For all the tools and newlib I selected configuration "powerpc- rtems". -------------------------------------------- IMD Ingenieurbuero fuer Microcomputertechnik Thomas Doerfler Herbststrasse 8 D-82178 Puchheim Germany email: td@imd.m.isar.de
Diffstat (limited to 'c/src/lib/libcpu/powerpc/ppc403/ictrl')
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/ictrl/Makefile.in61
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c250
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h84
3 files changed, 395 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/ppc403/ictrl/Makefile.in b/c/src/lib/libcpu/powerpc/ppc403/ictrl/Makefile.in
new file mode 100644
index 0000000000..551b527ead
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/ictrl/Makefile.in
@@ -0,0 +1,61 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/ictrl.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=ictrl
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=$(srcdir)/ictrl.h
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS += $(CFLAGS_OS_V)
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+ $(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE)
+
+# the .rel file built here will be put into libbsp.a by
+# libbsp/hppa/BSP/wrapup/Makefile
+install: all
diff --git a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c
new file mode 100644
index 0000000000..11d09f748a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c
@@ -0,0 +1,250 @@
+/* ictrl.c
+ *
+ * This routine installs and handles external interrupt vectors for
+ * PowerPC 403 CPU built-in external interrupt controller
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ *
+ * COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
+ *
+ * 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 IMD not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ */
+
+#include "ictrl.h"
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h> /* for atexit() */
+
+/*
+ * ISR vector table to dispatch external interrupts
+ */
+
+rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX];
+
+/*
+ *
+ * some utilities to access the EXI* registers
+ *
+ */
+
+/*
+ * clear bits in EXISR that have a bit set in mask
+ */
+RTEMS_INLINE_ROUTINE void
+clr_exisr(unsigned32 mask)
+{
+ asm volatile ("mtdcr 0x40,%0"::"r" (mask));/*EXISR*/
+}
+
+/*
+ * get value of EXISR
+ */
+RTEMS_INLINE_ROUTINE unsigned32
+get_exisr(void)
+{
+ unsigned32 val;
+
+ asm volatile ("mfdcr %0,0x40":"=r" (val));/*EXISR*/
+ return val;
+}
+
+/*
+ * get value of EXIER
+ */
+RTEMS_INLINE_ROUTINE unsigned32
+get_exier(void)
+{
+ unsigned32 val;
+ asm volatile ("mfdcr %0,0x42":"=r" (val));/*EXIER*/
+ return val;
+}
+
+/*
+ * set value of EXIER
+ */
+RTEMS_INLINE_ROUTINE void
+set_exier(unsigned32 val)
+{
+ asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
+}
+
+/*
+ * enable an external interrupt, make this interrupt consistent
+ */
+RTEMS_INLINE_ROUTINE void
+enable_ext_irq( unsigned32 mask)
+{
+ unsigned32 isrlvl;
+ _CPU_ISR_Disable(isrlvl);
+ set_exier(get_exier() | ((mask)&PPC_EXI_MASK));
+ _CPU_ISR_Enable(isrlvl);
+}
+
+/*
+ * disable an external interrupt, make this interrupt consistent
+ */
+RTEMS_INLINE_ROUTINE void
+disable_ext_irq( unsigned32 mask)
+{
+ unsigned32 isrlvl;
+ _CPU_ISR_Disable(isrlvl);
+ set_exier(get_exier() & ~(mask) & PPC_EXI_MASK);
+ _CPU_ISR_Enable(isrlvl);
+}
+
+/*
+ *
+ * this function is called, when a external interrupt is present and
+ * enabled but there is no handler installed. It will clear
+ * the corresponding enable bits and call the spurious handler
+ * present in the _CPU_Table, if any.
+ *
+ */
+void
+ictrl_spurious_handler(unsigned32 spurious_mask,
+ CPU_Interrupt_frame *cpu_frame)
+{
+ int v;
+
+ for (v=0; v < PPC_IRQ_EXT_MAX; v++) {
+ if (VEC_TO_EXMSK(v) & spurious_mask) {
+ clr_exisr(VEC_TO_EXMSK(v));
+ disable_ext_irq(VEC_TO_EXMSK(v));
+#if 0
+ printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
+ vector, cpu_frame->Interrupt.pcoqfront);
+#endif
+ if (_CPU_Table.spurious_handler) {
+ _CPU_Table.spurious_handler(v + PPC_IRQ_EXT_BASE,cpu_frame);
+ }
+ }
+ }
+}
+
+
+/*
+ * ISR Handler: this is called from the primary exception dispatcher
+ */
+
+void
+ictrl_isr(rtems_vector_number vector,CPU_Interrupt_frame *cpu_frame)
+{
+ unsigned32 istat,
+ mask,
+ global_vec;
+ int exvec;
+ rtems_isr_entry handler;
+
+ istat = get_exisr() & get_exier() & PPC_EXI_MASK;
+
+ /* FIXME: this may be speeded up using cntlzw instruction */
+ for (exvec = 0;exvec < PPC_IRQ_EXT_MAX;exvec++) {
+ mask = VEC_TO_EXMSK(exvec);
+ if (0 != (istat & mask)) {
+ clr_exisr(mask);
+ handler = ictrl_vector_table[exvec];
+ if (handler) {
+ istat &= ~mask;
+ global_vec = exvec + PPC_IRQ_EXT_BASE;
+ (handler)(global_vec);
+ }
+ }
+ }
+ if (istat != 0) { /* anything left? then we have a spurious interrupt */
+ ictrl_spurious_handler(istat,cpu_frame);
+ }
+}
+
+/*
+ *
+ * the following functions form the user interface
+ *
+ */
+
+/*
+ *
+ * install a user vector for one of the external interrupt sources
+ *
+ */
+rtems_status_code
+ictrl_set_vector(rtems_isr_entry new_handler,
+ unsigned32 vector,
+ rtems_isr_entry *old_handler
+)
+{
+ /*
+ * We put the actual user ISR address in 'ictrl_vector_table'. This will
+ * be used by the _ictrl_isr so the user gets control.
+ */
+
+ /* check for valid vector range */
+ if ((vector >= PPC_IRQ_EXT_BASE) &&
+ (vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
+
+ /* return old handler entry */
+ *old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
+
+ if (new_handler != NULL) {
+ /* store handler function... */
+ ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = new_handler;
+ /* then enable it in EXIER register */
+ enable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
+ }
+ else { /* new_handler == NULL */
+ /* then disable it in EXIER register */
+ disable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
+ ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = NULL;
+ }
+ return RTEMS_SUCCESSFUL;
+ }
+ else {
+ return RTEMS_INVALID_NUMBER;
+ }
+}
+
+/*
+ * Called via atexit()
+ * deactivate the interrupt controller
+ */
+
+void
+ictrl_exit(void)
+{
+ /* mark them all unused */
+ disable_ext_irq(~0);
+ clr_exisr(~0);
+
+}
+
+/*
+ * activate the interrupt controller
+ */
+
+rtems_status_code
+ictrl_init(void)
+{
+ proc_ptr dummy;
+
+ /* mark them all unused */
+ disable_ext_irq(~0);
+ clr_exisr(~0);
+
+ /* install the external interrupt handler */
+ _CPU_ISR_install_vector(PPC_IRQ_EXTERNAL,
+ ictrl_isr,
+ &dummy);
+ atexit(ictrl_exit);
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h
new file mode 100644
index 0000000000..5891d8aa2e
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h
@@ -0,0 +1,84 @@
+/* ictrl.h
+ *
+ * This file contains definitions and declarations for the
+ * PowerPC 403 CPU built-in external interrupt controller
+ *
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ *
+ * COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
+ *
+ * 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 IMD not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ */
+
+
+#ifndef _INCLUDE_ICTRL_h
+#define _INCLUDE_ICTRL_h
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * definitions for second level IRQ handler support
+ * External Interrupts via EXTERNAL/EISR
+ */
+#define PPC_IRQ_EXT_BASE (PPC_IRQ_LAST+1)
+
+/* mask for external interrupt status in EXIER/EXISR register */
+/* note: critical interrupt is in these registers aswell */
+#define PPC_EXI_MASK 0x0FFFFFFF
+
+#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
+#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
+#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
+#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
+#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
+#define PPC_IRQ_EXT_DMA1 (PPC_IRQ_EXT_BASE+9)
+#define PPC_IRQ_EXT_DMA2 (PPC_IRQ_EXT_BASE+10)
+#define PPC_IRQ_EXT_DMA3 (PPC_IRQ_EXT_BASE+11)
+#define PPC_IRQ_EXT_0 (PPC_IRQ_EXT_BASE+27)
+#define PPC_IRQ_EXT_1 (PPC_IRQ_EXT_BASE+28)
+#define PPC_IRQ_EXT_2 (PPC_IRQ_EXT_BASE+29)
+#define PPC_IRQ_EXT_3 (PPC_IRQ_EXT_BASE+30)
+#define PPC_IRQ_EXT_4 (PPC_IRQ_EXT_BASE+31)
+
+#define PPC_IRQ_EXT_MAX (32)
+
+#define VEC_TO_EXMSK(v) (0x80000000 >> (v))
+
+/*
+ *
+ * install a user vector for one of the external interrupt sources
+ *
+ */
+rtems_status_code
+ictrl_set_vector(rtems_isr_entry new_handler,
+ unsigned32 vector,
+ rtems_isr_entry *old_handler
+);
+/*
+ * activate the interrupt controller
+ */
+rtems_status_code
+ictrl_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! _INCLUDE_ICTRL_h */
+/* end of include file */