summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJennifer Averett <Jennifer.Averett@OARcorp.com>2004-11-22 22:13:35 +0000
committerJennifer Averett <Jennifer.Averett@OARcorp.com>2004-11-22 22:13:35 +0000
commit270ce1ff6802a56f5daf8329da252489e2c9286e (patch)
treeaac0abc18a1af1a8c1caf24cc1819b27f97c8165 /c
parent2004-11-22 Jennifer Averett <jennifer@OARcorp.com> (diff)
downloadrtems-270ce1ff6802a56f5daf8329da252489e2c9286e.tar.bz2
2004-11-22 Jennifer Averett <jennifer@OARcorp.com>
PR 581/bsps * Makefile.am, bsp_specs, configure.ac, include/bsp.h, include/tm27.h, start/start.S, startup/bspstart.c, startup/linkcmds, tools/Makefile.am, tools/psim, vectors/vectors.S, wrapup/Makefile.am: Convert PSIM to new exception model. * irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c: New files. * startup/setvec.c, timer/timer.c: Removed.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/psim/ChangeLog10
-rw-r--r--c/src/lib/libbsp/powerpc/psim/Makefile.am78
-rw-r--r--c/src/lib/libbsp/powerpc/psim/bsp_specs7
-rw-r--r--c/src/lib/libbsp/powerpc/psim/configure.ac2
-rw-r--r--c/src/lib/libbsp/powerpc/psim/include/bsp.h43
-rw-r--r--c/src/lib/libbsp/powerpc/psim/include/tm27.h26
-rw-r--r--c/src/lib/libbsp/powerpc/psim/irq/irq.c336
-rw-r--r--c/src/lib/libbsp/powerpc/psim/irq/irq.h333
-rw-r--r--c/src/lib/libbsp/powerpc/psim/irq/irq_asm.S357
-rw-r--r--c/src/lib/libbsp/powerpc/psim/irq/irq_init.c168
-rw-r--r--c/src/lib/libbsp/powerpc/psim/start/start.S9
-rw-r--r--c/src/lib/libbsp/powerpc/psim/startup/bspstart.c105
-rw-r--r--c/src/lib/libbsp/powerpc/psim/startup/linkcmds94
-rw-r--r--c/src/lib/libbsp/powerpc/psim/startup/setvec.c56
-rw-r--r--c/src/lib/libbsp/powerpc/psim/timer/timer.c70
-rw-r--r--c/src/lib/libbsp/powerpc/psim/tools/Makefile.am4
-rwxr-xr-xc/src/lib/libbsp/powerpc/psim/tools/psim4
-rw-r--r--c/src/lib/libbsp/powerpc/psim/vectors/vectors.S268
-rw-r--r--c/src/lib/libbsp/powerpc/psim/wrapup/Makefile.am13
19 files changed, 1627 insertions, 356 deletions
diff --git a/c/src/lib/libbsp/powerpc/psim/ChangeLog b/c/src/lib/libbsp/powerpc/psim/ChangeLog
index 39e632b9aa..4bb1d37a5b 100644
--- a/c/src/lib/libbsp/powerpc/psim/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/psim/ChangeLog
@@ -1,3 +1,13 @@
+2004-11-22 Jennifer Averett <jennifer@OARcorp.com>
+
+ PR 581/bsps
+ * Makefile.am, bsp_specs, configure.ac, include/bsp.h, include/tm27.h,
+ start/start.S, startup/bspstart.c, startup/linkcmds,
+ tools/Makefile.am, tools/psim, vectors/vectors.S, wrapup/Makefile.am:
+ Convert PSIM to new exception model.
+ * irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c: New files.
+ * startup/setvec.c, timer/timer.c: Removed.
+
2004-09-24 Ralf Corsepius <ralf_corsepius@rtems.org>
* configure.ac: Require automake > 1.9.
diff --git a/c/src/lib/libbsp/powerpc/psim/Makefile.am b/c/src/lib/libbsp/powerpc/psim/Makefile.am
index 7d4dce9628..3ff2c3b8dd 100644
--- a/c/src/lib/libbsp/powerpc/psim/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/psim/Makefile.am
@@ -21,6 +21,8 @@ EXTRA_PROGRAMS =
CLEANFILES =
noinst_DATA =
+include_bspdir = $(includedir)/bsp
+
include_HEADERS += include/coverhd.h
EXTRA_DIST = start/start.S
@@ -28,14 +30,18 @@ start$(LIB_VARIANT).$(OBJEXT): start/start.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
project_lib_DATA = start$(LIB_VARIANT).$(OBJEXT)
+EXTRA_DIST += ../../powerpc/shared/start/rtems_crti.S
+rtems_crti$(LIB_VARIANT).$(OBJEXT): ../../powerpc/shared/start/rtems_crti.S
+ $(CPPASCOMPILE) -DASM -o $@ -c $<
+project_lib_DATA += rtems_crti$(LIB_VARIANT).$(OBJEXT)
+
dist_project_lib_DATA += startup/linkcmds
EXTRA_PROGRAMS += startup.rel
CLEANFILES += startup.rel
startup_rel_SOURCES = startup/bspclean.c ../../shared/bsplibc.c \
../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
- ../../shared/main.c ../../shared/sbrk.c startup/setvec.c \
- ../../shared/gnatinstallhandler.c
+ ../../shared/main.c ../../shared/sbrk.c ../../shared/gnatinstallhandler.c
startup_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
@@ -47,19 +53,19 @@ startup_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_DATA += startup$(LIB_VARIANT).rel
-EXTRA_PROGRAMS += clock.rel
-CLEANFILES += clock.rel
-clock_rel_SOURCES = clock/clock.c
-clock_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
-clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+EXTRA_PROGRAMS += pclock.rel
+CLEANFILES += pclock.rel
+pclock_rel_SOURCES = ../shared/clock/p_clock.c
+pclock_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+pclock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
-EXTRA_PROGRAMS += clock_g.rel
-CLEANFILES += clock_g.rel
-clock_g_rel_SOURCES = $(clock_rel_SOURCES)
-clock_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
-clock_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+EXTRA_PROGRAMS += pclock_g.rel
+CLEANFILES += pclock_g.rel
+pclock_g_rel_SOURCES = $(pclock_rel_SOURCES)
+pclock_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+pclock_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
-noinst_DATA += clock$(LIB_VARIANT).rel
+noinst_DATA += pclock$(LIB_VARIANT).rel
EXTRA_PROGRAMS += console.rel
CLEANFILES += console.rel
@@ -76,25 +82,28 @@ console_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_DATA += console$(LIB_VARIANT).rel
-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)
+include_bsp_HEADERS = irq/irq.h
-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)
+EXTRA_PROGRAMS += irq.rel
+CLEANFILES += irq.rel
+irq_rel_SOURCES = irq/irq.c irq/irq_init.c irq/irq_asm.S
+irq_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
-noinst_DATA += timer$(LIB_VARIANT).rel
+EXTRA_PROGRAMS += irq_g.rel
+CLEANFILES += irq_g.rel
+irq_g_rel_SOURCES = $(irq_rel_SOURCES)
+irq_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+irq_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += irq$(LIB_VARIANT).rel
EXTRA_DIST += vectors/README
EXTRA_PROGRAMS += vectors.rel
CLEANFILES += vectors.rel
-vectors_rel_SOURCES = vectors/align_h.S vectors/vectors.S
+vectors_rel_SOURCES = vectors/align_h.S vectors/vectors.S \
+ ../../powerpc/shared/vectors/vectors_init.c
vectors_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
@@ -106,6 +115,8 @@ vectors_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_DATA += vectors$(LIB_VARIANT).rel
+include_bsp_HEADERS += ../../powerpc/shared/vectors/vectors.h
+
if HAS_MP
EXTRA_DIST += shmsupp/README
@@ -157,14 +168,31 @@ $(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/bsp
+ @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
$(PROJECT_INCLUDE)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+$(PROJECT_INCLUDE)/bsp/irq.h: irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
+$(PROJECT_INCLUDE)/bsp/vectors.h: ../shared/vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
+
$(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT): start$(LIB_VARIANT).$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
+$(PROJECT_LIB)/rtems_crti$(LIB_VARIANT).$(OBJEXT): rtems_crti$(LIB_VARIANT).$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/rtems_crti$(LIB_VARIANT).$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/rtems_crti$(LIB_VARIANT).$(OBJEXT)
+
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
diff --git a/c/src/lib/libbsp/powerpc/psim/bsp_specs b/c/src/lib/libbsp/powerpc/psim/bsp_specs
index a6fe34bec4..354c8b093a 100644
--- a/c/src/lib/libbsp/powerpc/psim/bsp_specs
+++ b/c/src/lib/libbsp/powerpc/psim/bsp_specs
@@ -3,13 +3,12 @@
%rename link old_link
*startfile:
-%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: ecrti%O%s \
+%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s \
%{!qrtems_debug: start.o%s} \
%{qrtems_debug: start_g.o%s}}}
-*endfile:
-%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
-
*link:
%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -e _start -u __vectors}
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/c/src/lib/libbsp/powerpc/psim/configure.ac b/c/src/lib/libbsp/powerpc/psim/configure.ac
index 342f66dfde..e7a690fcc6 100644
--- a/c/src/lib/libbsp/powerpc/psim/configure.ac
+++ b/c/src/lib/libbsp/powerpc/psim/configure.ac
@@ -33,6 +33,6 @@ RTEMS_BSPOPTS_HELP([PPC_VECTOR_FILE_BASE],
AC_CONFIG_FILES([Makefile
wrapup/Makefile])
-RTEMS_PPC_EXCEPTIONS([old])
+RTEMS_PPC_EXCEPTIONS([new])
AC_OUTPUT
diff --git a/c/src/lib/libbsp/powerpc/psim/include/bsp.h b/c/src/lib/libbsp/powerpc/psim/include/bsp.h
index 5821fcc1ab..6103728312 100644
--- a/c/src/lib/libbsp/powerpc/psim/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/psim/include/bsp.h
@@ -54,64 +54,41 @@ extern "C" {
#else
#include <rtems.h>
#include <rtems/console.h>
+#include <libcpu/io.h>
#include <rtems/clockdrv.h>
-#include <rtems/console.h>
#include <rtems/iosupp.h>
+#include <bsp/vectors.h>
/* Constants */
/*
- * Device Driver Table Entries
+ * Information placed in the linkcmds file.
*/
+extern int RAM_END;
+extern int end; /* last address in the program */
+
/*
- * NOTE: Use the standard Console driver entry
+ * Device Driver Table Entries
*/
/*
- * NOTE: Use the standard Clock driver entry
+ * NOTE: Use the standard Console driver entry
*/
/*
- * Information placed in the linkcmds file.
+ * NOTE: Use the standard Clock driver entry
*/
-extern int RAM_START;
-extern int RAM_END;
-extern int RAM_SIZE;
-
-extern int PROM_START;
-extern int PROM_END;
-extern int PROM_SIZE;
-
-extern int CLOCK_SPEED;
-
-extern int end; /* last address in the program */
+#define BSP_Convert_decrementer( _value ) ( (unsigned long long) _value )
/* functions */
-void bsp_start( void );
-
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 */
-);
-
-void DEBUG_puts( char *string );
-
-void BSP_fatal_return( void );
-
-void bsp_spurious_initialize( void );
-
extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
-
extern rtems_cpu_table Cpu_table; /* owned by BSP */
-extern uint32_t bsp_isr_level;
-
#endif /* ASM */
#ifdef __cplusplus
diff --git a/c/src/lib/libbsp/powerpc/psim/include/tm27.h b/c/src/lib/libbsp/powerpc/psim/include/tm27.h
index f66b5bc85f..0393260509 100644
--- a/c/src/lib/libbsp/powerpc/psim/include/tm27.h
+++ b/c/src/lib/libbsp/powerpc/psim/include/tm27.h
@@ -15,30 +15,46 @@
#ifndef __tm27_h
#define __tm27_h
+#include <bsp/irq.h>
+
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 1
-#define Install_tm27_vector( _handler ) \
- set_vector( (_handler), PPC_IRQ_DECREMENTER, 1 )
+void nullFunc() {}
+static rtems_irq_connect_data clockIrqData = {BSP_DECREMENTER,
+ 0,
+ (rtems_irq_enable)nullFunc,
+ (rtems_irq_disable)nullFunc,
+ (rtems_irq_is_enabled) nullFunc};
+
+void Install_tm27_vector(void (*_handler)())
+{
+ clockIrqData.hdl = _handler;
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
+ printk("Error installing clock interrupt handler!\n");
+ rtems_fatal_error_occurred(1);
+ }
+}
#define Cause_tm27_intr() \
do { \
- uint32_t _clicks = 1; \
+ unsigned32 _clicks = 1; \
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
} while (0)
+
#define Clear_tm27_intr() \
do { \
- uint32_t _clicks = 0xffffffff; \
+ unsigned32 _clicks = 0xffffffff; \
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
} while (0)
#define Lower_tm27_intr() \
do { \
- uint32_t _msr = 0; \
+ unsigned32 _msr = 0; \
_ISR_Set_level( 0 ); \
asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
_msr |= 0x8002; \
diff --git a/c/src/lib/libbsp/powerpc/psim/irq/irq.c b/c/src/lib/libbsp/powerpc/psim/irq/irq.c
new file mode 100644
index 0000000000..6572d3c467
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/psim/irq/irq.c
@@ -0,0 +1,336 @@
+/*
+ *
+ * This file contains the implementation of the function described in irq.h
+ *
+ * Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * irq.c,v 1.4.2.8 2003/09/04 18:45:20 joel Exp
+ */
+
+#include <rtems/system.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#if 0
+#include <bsp/VME.h>
+#include <bsp/openpic.h>
+#endif
+#include <stdlib.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/io.h>
+#include <bsp/vectors.h>
+
+#include <rtems/bspIo.h> /* for printk */
+#define RAVEN_INTR_ACK_REG 0xfeff0030
+
+/*
+ * pointer to the mask representing the additionnal irq vectors
+ * that must be disabled when a particular entry is activated.
+ * They will be dynamically computed from teh prioruty table given
+ * in BSP_rtems_irq_mngt_set();
+ * CAUTION : this table is accessed directly by interrupt routine
+ * prologue.
+ */
+rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER];
+/*
+ * default handler connected on each irq after bsp initialization
+ */
+static rtems_irq_connect_data default_rtems_entry;
+
+/*
+ * location used to store initial tables used for interrupt
+ * management.
+ */
+static rtems_irq_global_settings* internal_config;
+static rtems_irq_connect_data* rtems_hdl_tbl;
+
+/*
+ * Check if IRQ is an ISA IRQ
+ */
+static inline int is_isa_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * Check if IRQ is an OPENPIC IRQ
+ */
+static inline int is_pci_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * Check if IRQ is a Porcessor IRQ
+ */
+static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
+ );
+}
+
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * This function check that the value given for the irq line
+ * is valid.
+ */
+
+static int isValidInterrupt(int irq)
+{
+ if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
+ return 0;
+ return 1;
+}
+
+
+/*
+ * ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
+ */
+int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
+{
+ printk("BSP_insall_rtems_shared_irq_handler Not supported in psim\n");
+ return 0;
+}
+
+
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ printk("Invalid interrupt vector %d\n",irq->name);
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via i386_get_current_idt_entry
+ * and then disconnect it using i386_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ _CPU_ISR_Disable(level);
+ if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
+ _CPU_ISR_Enable(level);
+ printk("IRQ vector %d already connected\n",irq->name);
+ return 0;
+ }
+
+ /*
+ * store the data provided by user
+ */
+ rtems_hdl_tbl[irq->name] = *irq;
+ rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
+
+ if (is_isa_irq(irq->name)) {
+ printk("What's a isa_irq on psim?");
+ }
+
+ if (is_processor_irq(irq->name)) {
+ /*
+ * Enable exception at processor level
+ */
+ }
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ *irq = rtems_hdl_tbl[irq->name];
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via i386_get_current_idt_entry
+ * and then disconnect it using i386_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ _CPU_ISR_Disable(level);
+ if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+
+ if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
+ {
+ int found = 0;
+
+ for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
+ (vchain->hdl != default_rtems_entry.hdl);
+ (pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
+ {
+ if( vchain->hdl == irq->hdl )
+ {
+ found= -1; break;
+ }
+ }
+
+ if( !found )
+ {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ }
+ else
+ {
+ if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
+ {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ }
+
+ if (is_isa_irq(irq->name)) {
+ printk("isa irq on psim?");
+ }
+ if (is_processor_irq(irq->name)) {
+ /*
+ * disable exception at processor level
+ */
+ }
+
+ /*
+ * Disable interrupt on device
+ */
+ irq->off(irq);
+
+ /*
+ * restore the default irq value
+ */
+ if( !vchain )
+ {
+ /* single handler vector... */
+ rtems_hdl_tbl[irq->name] = default_rtems_entry;
+ }
+ else
+ {
+ if( pchain )
+ {
+ /* non-first handler being removed */
+ pchain->next_handler = vchain->next_handler;
+ }
+ else
+ {
+ /* first handler isn't malloc'ed, so just overwrite it. Since
+ the contents of vchain are being struct copied, vchain itself
+ goes away */
+ rtems_hdl_tbl[irq->name]= *vchain;
+ }
+ free(vchain);
+ }
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+{
+ /*
+ * Store various code accelerators
+ */
+ internal_config = config;
+ default_rtems_entry = config->defaultEntry;
+ rtems_hdl_tbl = config->irqHdlTbl;
+
+ return 1;
+}
+
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+{
+ *config = internal_config;
+ return 0;
+}
+
+int _BSP_vme_bridge_irq = -1;
+
+unsigned BSP_spuriousIntr = 0;
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
+{
+ register unsigned msr;
+ register unsigned new_msr;
+
+ if (excNum == ASM_DEC_VECTOR) {
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ rtems_hdl_tbl[BSP_DECREMENTER].hdl();
+
+ _CPU_MSR_SET(msr);
+ return;
+
+ }
+}
+
+
+
+void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
+{
+ /*
+ * Process pending signals that have not already been
+ * processed by _Thread_Displatch. This happens quite
+ * unfrequently : the ISR must have posted an action
+ * to the current running thread.
+ */
+ if ( _Thread_Do_post_task_switch_extension ||
+ _Thread_Executing->do_post_task_switch_extension ) {
+ _Thread_Executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+ }
+ /*
+ * I plan to process other thread related events here.
+ * This will include DEBUG session requested from keyboard...
+ */
+}
diff --git a/c/src/lib/libbsp/powerpc/psim/irq/irq.h b/c/src/lib/libbsp/powerpc/psim/irq/irq.h
new file mode 100644
index 0000000000..3d61db06e2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/psim/irq/irq.h
@@ -0,0 +1,333 @@
+/* irq.h
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to write interrupt handlers.
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * This code is heavilly inspired by the public specification of STREAM V2
+ * that can be found at :
+ *
+ * <http://www.chorus.com/Documentation/index.html> by following
+ * the STREAM API Specification Document link.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * irq.h,v 1.2.4.2 2003/09/04 18:45:20 joel Exp
+ */
+
+#ifndef LIBBSP_POWERPC_MCP750_IRQ_IRQ_H
+#define LIBBSP_POWERPC_MCP750_IRQ_IRQ_H
+
+
+/*
+ * 8259 edge/level control definitions at VIA
+ */
+#define ISA8259_M_ELCR 0x4d0
+#define ISA8259_S_ELCR 0x4d1
+
+#define ELCRS_INT15_LVL 0x80
+#define ELCRS_INT14_LVL 0x40
+#define ELCRS_INT13_LVL 0x20
+#define ELCRS_INT12_LVL 0x10
+#define ELCRS_INT11_LVL 0x08
+#define ELCRS_INT10_LVL 0x04
+#define ELCRS_INT9_LVL 0x02
+#define ELCRS_INT8_LVL 0x01
+#define ELCRM_INT7_LVL 0x80
+#define ELCRM_INT6_LVL 0x40
+#define ELCRM_INT5_LVL 0x20
+#define ELCRM_INT4_LVL 0x10
+#define ELCRM_INT3_LVL 0x8
+#define ELCRM_INT2_LVL 0x4
+#define ELCRM_INT1_LVL 0x2
+#define ELCRM_INT0_LVL 0x1
+
+#define BSP_ASM_IRQ_VECTOR_BASE 0x0
+ /* PIC's command and mask registers */
+#define PIC_MASTER_COMMAND_IO_PORT 0x20 /* Master PIC command register */
+#define PIC_SLAVE_COMMAND_IO_PORT 0xa0 /* Slave PIC command register */
+#define PIC_MASTER_IMR_IO_PORT 0x21 /* Master PIC Interrupt Mask Register */
+#define PIC_SLAVE_IMR_IO_PORT 0xa1 /* Slave PIC Interrupt Mask Register */
+
+ /* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */
+#define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */
+#define SLAVE_PIC_EOSI 0x62 /* End of Specific Interrupt (EOSI) for cascade */
+#define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */
+
+#ifndef ASM
+
+
+/*
+ * Symblolic IRQ names and related definitions.
+ */
+
+typedef enum {
+ /* Base vector for our ISA IRQ handlers. */
+ BSP_ISA_IRQ_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE,
+ /*
+ * ISA IRQ handler related definitions
+ */
+ BSP_ISA_IRQ_NUMBER = 16,
+ BSP_ISA_IRQ_LOWEST_OFFSET = 0,
+ BSP_ISA_IRQ_MAX_OFFSET = BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER - 1,
+ /*
+ * PCI IRQ handlers related definitions
+ * CAUTION : BSP_PCI_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE
+ */
+ BSP_PCI_IRQ_NUMBER = 16,
+ BSP_PCI_IRQ_LOWEST_OFFSET = BSP_ISA_IRQ_NUMBER,
+ BSP_PCI_IRQ_MAX_OFFSET = BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER - 1,
+ /*
+ * PowerPc exceptions handled as interrupt where a rtems managed interrupt
+ * handler might be connected
+ */
+ BSP_PROCESSOR_IRQ_NUMBER = 1,
+ BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_PCI_IRQ_MAX_OFFSET + 1,
+ BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1,
+ /* Misc vectors for OPENPIC irqs (IPI, timers)
+ */
+ BSP_MISC_IRQ_NUMBER = 8,
+ BSP_MISC_IRQ_LOWEST_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1,
+ BSP_MISC_IRQ_MAX_OFFSET = BSP_MISC_IRQ_LOWEST_OFFSET + BSP_MISC_IRQ_NUMBER - 1,
+ /*
+ * Summary
+ */
+ BSP_IRQ_NUMBER = BSP_MISC_IRQ_MAX_OFFSET + 1,
+ BSP_LOWEST_OFFSET = BSP_ISA_IRQ_LOWEST_OFFSET,
+ BSP_MAX_OFFSET = BSP_MISC_IRQ_MAX_OFFSET,
+ /*
+ * Some ISA IRQ symbolic name definition
+ */
+ BSP_ISA_PERIODIC_TIMER = 0,
+
+ BSP_ISA_KEYBOARD = 1,
+
+ BSP_ISA_UART_COM2_IRQ = 3,
+
+ BSP_ISA_UART_COM1_IRQ = 4,
+
+ BSP_ISA_RT_TIMER1 = 8,
+
+ BSP_ISA_RT_TIMER3 = 10,
+ /*
+ * Some PCI IRQ symbolic name definition
+ */
+ BSP_PCI_IRQ0 = BSP_PCI_IRQ_LOWEST_OFFSET,
+ BSP_PCI_ISA_BRIDGE_IRQ = BSP_PCI_IRQ0,
+ /*
+ * Some Processor execption handled as rtems IRQ symbolic name definition
+ */
+ BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET
+
+}rtems_irq_symbolic_name;
+
+
+
+
+/*
+ * Type definition for RTEMS managed interrupts
+ */
+typedef unsigned char rtems_irq_prio;
+typedef unsigned short rtems_i8259_masks;
+
+extern volatile rtems_i8259_masks i8259s_cache;
+
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+
+typedef void (*rtems_irq_hdl) (void);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
+
+typedef struct __rtems_irq_connect_data__ {
+ /*
+ * IRQ line
+ */
+ rtems_irq_symbolic_name name;
+ /*
+ * handler. See comment on handler properties below in function prototype.
+ */
+ rtems_irq_hdl hdl;
+ /*
+ * function for enabling interrupts at device level (ONLY!).
+ * The BSP code will automatically enable it at i8259s level and openpic level.
+ * RATIONALE : anyway such code has to exist in current driver code.
+ * It is usually called immediately AFTER connecting the interrupt handler.
+ * RTEMS may well need such a function when restoring normal interrupt
+ * processing after a debug session.
+ *
+ */
+ rtems_irq_enable on;
+ /*
+ * function for disabling interrupts at device level (ONLY!).
+ * The code will disable it at i8259s level. RATIONALE : anyway
+ * such code has to exist for clean shutdown. It is usually called
+ * BEFORE disconnecting the interrupt. RTEMS may well need such
+ * a function when disabling normal interrupt processing for
+ * a debug session. May well be a NOP function.
+ */
+ rtems_irq_disable off;
+ /*
+ * function enabling to know what interrupt may currently occur
+ * if someone manipulates the i8259s interrupt mask without care...
+ */
+ rtems_irq_is_enabled isOn;
+ /*
+ * Set to -1 for vectors forced to have only 1 handler
+ */
+ void *next_handler;
+
+}rtems_irq_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int irqNb;
+ /*
+ * Default handler used when disconnecting interrupts.
+ */
+ rtems_irq_connect_data defaultEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_irq_connect_data* irqHdlTbl;
+ /*
+ * actual value of BSP_ISA_IRQ_VECTOR_BASE...
+ */
+ rtems_irq_symbolic_name irqBase;
+ /*
+ * software priorities associated with interrupts.
+ * if irqPrio [i] > intrPrio [j] it means that
+ * interrupt handler hdl connected for interrupt name i
+ * will not be interrupted by the handler connected for interrupt j
+ * The interrupt source will be physically masked at i8259 level.
+ */
+ rtems_irq_prio* irqPrioTbl;
+}rtems_irq_global_settings;
+
+
+
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+/*
+ * ------------------------ Intel 8259 (or emulation) Mngt Routines -------
+ */
+
+/*
+ * function to disable a particular irq at 8259 level. After calling
+ * this function, even if the device asserts the interrupt line it will
+ * not be propagated further to the processor
+ */
+int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to enable a particular irq at 8259 level. After calling
+ * this function, if the device asserts the interrupt line it will
+ * be propagated further to the processor
+ */
+int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to acknoledge a particular irq at 8259 level. After calling
+ * this function, if a device asserts an enabled interrupt line it will
+ * be propagated further to the processor. Mainly usefull for people
+ * writting raw handlers as this is automagically done for rtems managed
+ * handlers.
+ */
+int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to check if a particular irq is enabled at 8259 level. After calling
+ */
+int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine);
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+/*
+ * function to connect a particular irq handler. This hanlder will NOT be called
+ * directly as the result of the corresponding interrupt. Instead, a RTEMS
+ * irq prologue will be called that will :
+ *
+ * 1) save the C scratch registers,
+ * 2) switch to a interrupt stack if the interrupt is not nested,
+ * 3) store the current i8259s' interrupt masks
+ * 4) modify them to disable the current interrupt at 8259 level (and may
+ * be others depending on software priorities)
+ * 5) aknowledge the i8259s',
+ * 6) demask the processor,
+ * 7) call the application handler
+ *
+ * As a result the hdl function provided
+ *
+ * a) can perfectly be written is C,
+ * b) may also well directly call the part of the RTEMS API that can be used
+ * from interrupt level,
+ * c) It only responsible for handling the jobs that need to be done at
+ * the device level including (aknowledging/re-enabling the interrupt at device,
+ * level, getting the data,...)
+ *
+ * When returning from the function, the following will be performed by
+ * the RTEMS irq epilogue :
+ *
+ * 1) masks the interrupts again,
+ * 2) restore the original i8259s' interrupt masks
+ * 3) switch back on the orinal stack if needed,
+ * 4) perform rescheduling when necessary,
+ * 5) restore the C scratch registers...
+ * 6) restore initial execution flow
+ *
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
+int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data*);
+
+#define BSP_SHARED_HANDLER_SUPPORT 1
+
+/*
+ * function to get the current RTEMS irq handler for ptr->name. It enables to
+ * define hanlder chain...
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+/*
+ * function to get disconnect the RTEMS irq handler for ptr->name.
+ * This function checks that the value given is the current one for safety reason.
+ * The user can use the previous function to get it.
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+
+/*
+ * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+/*
+ * (Re) Initialize the RTEMS interrupt management.
+ *
+ * The result of calling this function will be the same as if each individual
+ * handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl"
+ * has been individualy connected via
+ * BSP_install_rtems_irq_handler(&config->irqHdlTbl[i])
+ * And each handler currently equal to config->defaultEntry.hdl
+ * has been previously disconnected via
+ * BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i])
+ *
+ * This is to say that all information given will be used and not just
+ * only the space.
+ *
+ * CAUTION : the various table address contained in config will be used
+ * directly by the interrupt mangement code in order to save
+ * data size so they must stay valid after the call => they should
+ * not be modified or declared on a stack.
+ */
+
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**);
+
+extern void BSP_rtems_irq_mng_init(unsigned cpuId);
+extern void BSP_i8259s_init(void);
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/psim/irq/irq_asm.S b/c/src/lib/libbsp/powerpc/psim/irq/irq_asm.S
new file mode 100644
index 0000000000..dfaba64ab7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/psim/irq/irq_asm.S
@@ -0,0 +1,357 @@
+/*
+ * This file contains the assembly code for the PowerPC
+ * IRQ veneers for RTEMS.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 2003/7:
+ * - store isr nesting level in _ISR_Nest_level rather than
+ * SPRG0 - RTEMS relies on that variable.
+ *
+ * irq_asm.S,v 1.5.4.3 2003/09/04 18:45:20 joel Exp
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+#include <bsp/vectors.h>
+#include <libcpu/raw_exception.h>
+
+
+#define SYNC \
+ sync; \
+ isync
+
+ .text
+ .p2align 5
+
+ PUBLIC_VAR(decrementer_exception_vector_prolog_code)
+
+SYM (decrementer_exception_vector_prolog_code):
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, ASM_DEC_VECTOR
+ ba shared_raw_irq_code_entry
+
+ PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
+
+ decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
+
+ PUBLIC_VAR(external_exception_vector_prolog_code)
+
+SYM (external_exception_vector_prolog_code):
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, ASM_EXT_VECTOR
+ ba shared_raw_irq_code_entry
+
+ PUBLIC_VAR (external_exception_vector_prolog_code_size)
+
+ external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
+
+ PUBLIC_VAR(shared_raw_irq_code_entry)
+ PUBLIC_VAR(C_dispatch_irq_handler)
+
+ .p2align 5
+SYM (shared_raw_irq_code_entry):
+ /*
+ * Entry conditions :
+ * Registers already saved : R1, R4
+ * R1 : points to a location with enough room for the
+ * interrupt frame
+ * R4 : vector number
+ */
+ /*
+ * Save SRR0/SRR1 As soon As possible as it is the minimal needed
+ * to reenable exception processing
+ */
+ stw r0, GPR0_OFFSET(r1)
+ /* PPC EABI: R2 is reserved (pointer to short data .sdata2) - we won't touch it
+ * but we still save/restore it, just in case...
+ */
+ stw r2, GPR2_OFFSET(r1)
+ stw r3, GPR3_OFFSET(r1)
+
+ mfsrr0 r0
+ mfsrr1 r3
+
+ stw r0, SRR0_FRAME_OFFSET(r1)
+ stw r3, SRR1_FRAME_OFFSET(r1)
+
+ mfmsr r3
+ /*
+ * Enable data and instruction address translation, exception recovery
+ *
+ * also, on CPUs with FP, enable FP so that FP context can be
+ * saved and restored (using FP instructions)
+ */
+#if (PPC_HAS_FPU == 0)
+ ori r3, r3, MSR_RI | MSR_IR | MSR_DR
+#else
+ ori r3, r3, MSR_RI | MSR_FP /* MSR_IR | MSR_DR */
+#endif
+ mtmsr r3
+ SYNC
+ /*
+ * Push C scratch registers on the current stack. It may
+ * actually be the thread stack or the interrupt stack.
+ * Anyway we have to make it in order to be able to call C/C++
+ * functions. Depending on the nesting interrupt level, we will
+ * switch to the right stack later.
+ */
+ stw r5, GPR5_OFFSET(r1)
+ stw r6, GPR6_OFFSET(r1)
+ stw r7, GPR7_OFFSET(r1)
+ stw r8, GPR8_OFFSET(r1)
+ stw r9, GPR9_OFFSET(r1)
+ stw r10, GPR10_OFFSET(r1)
+ stw r11, GPR11_OFFSET(r1)
+ stw r12, GPR12_OFFSET(r1)
+ stw r13, GPR13_OFFSET(r1)
+
+ mfcr r5
+ mfctr r6
+ mfxer r7
+ mflr r8
+
+ stw r5, EXC_CR_OFFSET(r1)
+ stw r6, EXC_CTR_OFFSET(r1)
+ stw r7, EXC_XER_OFFSET(r1)
+ stw r8, EXC_LR_OFFSET(r1)
+
+ /*
+ * Add some non volatile registers to store information
+ * that will be used when returning from C handler
+ */
+ stw r14, GPR14_OFFSET(r1)
+ stw r15, GPR15_OFFSET(r1)
+ /*
+ * save current stack pointer location in R14
+ */
+ addi r14, r1, 0
+ /*
+ * store part of _Thread_Dispatch_disable_level address in R15
+ */
+ addis r15,0, _Thread_Dispatch_disable_level@ha
+#if BROKEN_ISR_NEST_LEVEL
+ /*
+ * Get current nesting level in R3
+ */
+ mfspr r3, SPRG0
+#else
+ /*
+ * Retrieve current nesting level from _ISR_Nest_level
+ */
+ lis r7, _ISR_Nest_level@ha
+ lwz r3, _ISR_Nest_level@l(r7)
+#endif
+ /*
+ * Check if stack switch is necessary
+ */
+ cmpwi r3,0
+ bne nested
+ mfspr r1, SPRG1
+
+nested:
+ /*
+ * Start Incrementing nesting level in R3
+ */
+ addi r3,r3,1
+ /*
+ * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
+ */
+ lwz r6,_Thread_Dispatch_disable_level@l(r15)
+#if BROKEN_ISR_NEST_LEVEL
+ /*
+ * Store new nesting level in SPRG0
+ */
+ mtspr SPRG0, r3
+#else
+ /* store new nesting level in _ISR_Nest_level */
+ stw r3, _ISR_Nest_level@l(r7)
+#endif
+
+ addi r6, r6, 1
+ mfmsr r5
+ /*
+ * store new _Thread_Dispatch_disable_level value
+ */
+ stw r6, _Thread_Dispatch_disable_level@l(r15)
+ /*
+ * We are now running on the interrupt stack. External and decrementer
+ * exceptions are still disabled. I see no purpose trying to optimize
+ * further assembler code.
+ */
+ /*
+ * Call C exception handler for decrementer Interrupt frame is passed just
+ * in case...
+ */
+ addi r3, r14, 0x8
+ bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
+ /*
+ * start decrementing nesting level. Note : do not test result against 0
+ * value as an easy exit condition because if interrupt nesting level > 1
+ * then _Thread_Dispatch_disable_level > 1
+ */
+#if BROKEN_ISR_NEST_LEVEL
+ mfspr r4, SPRG0
+#else
+ lis r7, _ISR_Nest_level@ha
+ lwz r4, _ISR_Nest_level@l(r7)
+#endif
+ /*
+ * start decrementing _Thread_Dispatch_disable_level
+ */
+ lwz r3,_Thread_Dispatch_disable_level@l(r15)
+ addi r4, r4, -1 /* Continue decrementing nesting level */
+ addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
+#if BROKEN_ISR_NEST_LEVEL
+ mtspr SPRG0, r4 /* End decrementing nesting level */
+#else
+ stw r4, _ISR_Nest_level@l(r7) /* End decrementing nesting level */
+#endif
+ stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
+ cmpwi r3, 0
+ /*
+ * switch back to original stack (done here just optimize registers
+ * contention. Could have been done before...)
+ */
+ addi r1, r14, 0
+ bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
+ /*
+ * Here we are running again on the thread system stack.
+ * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
+ * Interrupt are still disabled. Time to check if scheduler request to
+ * do something with the current thread...
+ */
+ addis r4, 0, _Context_Switch_necessary@ha
+ lwz r5, _Context_Switch_necessary@l(r4)
+ cmpwi r5, 0
+ bne switch
+
+ addis r6, 0, _ISR_Signals_to_thread_executing@ha
+ lwz r7, _ISR_Signals_to_thread_executing@l(r6)
+ cmpwi r7, 0
+ li r8, 0
+ beq easy_exit
+ stw r8, _ISR_Signals_to_thread_executing@l(r6)
+ /*
+ * going to call _ThreadProcessSignalsFromIrq
+ * Push a complete exception like frame...
+ */
+ stmw r16, GPR16_OFFSET(r1)
+ addi r3, r1, 0x8
+ /*
+ * compute SP at exception entry
+ */
+ addi r4, r1, EXCEPTION_FRAME_END
+ /*
+ * store it at the right place
+ */
+ stw r4, GPR1_OFFSET(r1)
+ /*
+ * Call High Level signal handling code
+ */
+ bl _ThreadProcessSignalsFromIrq
+ /*
+ * start restoring exception like frame
+ */
+ lwz r31, EXC_CTR_OFFSET(r1)
+ lwz r30, EXC_XER_OFFSET(r1)
+ lwz r29, EXC_CR_OFFSET(r1)
+ lwz r28, EXC_LR_OFFSET(r1)
+
+ mtctr r31
+ mtxer r30
+ mtcr r29
+ mtlr r28
+
+ lmw r4, GPR4_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ /*
+ * Disable data and instruction translation. Make path non recoverable...
+ */
+ mfmsr r3
+ xori r3, r3, MSR_RI /* | MSR_IR | MSR_DR */
+ mtmsr r3
+ SYNC
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r3, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r3
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r3
+
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
+switch:
+ bl SYM (_Thread_Dispatch)
+
+easy_exit:
+ /*
+ * start restoring interrupt frame
+ */
+ lwz r3, EXC_CTR_OFFSET(r1)
+ lwz r4, EXC_XER_OFFSET(r1)
+ lwz r5, EXC_CR_OFFSET(r1)
+ lwz r6, EXC_LR_OFFSET(r1)
+
+ mtctr r3
+ mtxer r4
+ mtcr r5
+ mtlr r6
+
+ lwz r15, GPR15_OFFSET(r1)
+ lwz r14, GPR14_OFFSET(r1)
+ lwz r13, GPR13_OFFSET(r1)
+ lwz r12, GPR12_OFFSET(r1)
+ lwz r11, GPR11_OFFSET(r1)
+ lwz r10, GPR10_OFFSET(r1)
+ lwz r9, GPR9_OFFSET(r1)
+ lwz r8, GPR8_OFFSET(r1)
+ lwz r7, GPR7_OFFSET(r1)
+ lwz r6, GPR6_OFFSET(r1)
+ lwz r5, GPR5_OFFSET(r1)
+
+ /*
+ * Disable nested exception processing, data and instruction
+ * translation.
+ */
+ mfmsr r3
+ xori r3, r3, MSR_RI /* | MSR_IR | MSR_DR */
+ mtmsr r3
+ SYNC
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r4, SRR1_FRAME_OFFSET(r1)
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ mtsrr1 r4
+ mtsrr0 r3
+ lwz r4, GPR4_OFFSET(r1)
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
diff --git a/c/src/lib/libbsp/powerpc/psim/irq/irq_init.c b/c/src/lib/libbsp/powerpc/psim/irq/irq_init.c
new file mode 100644
index 0000000000..7ecc827bec
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/psim/irq/irq_init.c
@@ -0,0 +1,168 @@
+/* irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to make it valid for MVME2300 Motorola boards.
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
+ * Use the new interface to openpic_init
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * irq_init.c,v 1.6.2.5 2003/09/04 18:45:20 joel Exp
+ */
+
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/raw_exception.h>
+#include <rtems/bspIo.h>
+#if 0
+#include <bsp/pci.h>
+#include <bsp/residual.h>
+#include <bsp/openpic.h>
+#include <bsp/motorola.h>
+#endif
+
+
+/*
+#define SHOW_ISA_PCI_BRIDGE_SETTINGS
+*/
+
+typedef struct {
+ unsigned char bus; /* few chance the PCI/ISA bridge is not on first bus but ... */
+ unsigned char device;
+ unsigned char function;
+} pci_isa_bridge_device;
+
+pci_isa_bridge_device* via_82c586 = 0;
+
+extern unsigned int external_exception_vector_prolog_code_size[];
+extern void external_exception_vector_prolog_code();
+extern unsigned int decrementer_exception_vector_prolog_code_size[];
+extern void decrementer_exception_vector_prolog_code();
+
+/*
+ * default on/off function
+ */
+static void nop_func(){}
+/*
+ * default isOn function
+ */
+static int not_connected() {return 0;}
+/*
+ * default possible isOn function
+ */
+static int connected() {return 1;}
+
+static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings initial_config;
+static rtems_irq_connect_data defaultIrq = {
+ /* vectorIdex, hdl , on , off , isOn */
+ 0, nop_func , nop_func , nop_func , not_connected
+};
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+ /*
+ * actual rpiorities for interrupt :
+ * 0 means that only current interrupt is masked
+ * 255 means all other interrupts are masked
+ */
+ /*
+ * ISA interrupts.
+ * The second entry has a priority of 255 because
+ * it is the slave pic entry and is should always remain
+ * unmasked.
+ */
+ 0,0,
+ 255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /*
+ * PCI Interrupts
+ */
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
+ /*
+ * Processor exceptions handled as interrupts
+ */
+ 0
+};
+
+void VIA_isa_bridge_interrupts_setup(void)
+{
+ printk("VIA_isa_bridge_interrupts_setup - Shouldn't get here!\n");
+ return;
+}
+
+ /*
+ * This code assumes the exceptions management setup has already
+ * been done. We just need to replace the exceptions that will
+ * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+ * this means the decrementer exception and the external exception.
+ */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+ rtems_raw_except_connect_data vectorDesc;
+ int i;
+
+ /*
+ * First initialize the Interrupt management hardware
+ */
+
+ /*
+ * Initialize Rtems management interrupt table
+ */
+ /*
+ * re-init the rtemsIrq table
+ */
+ for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+ rtemsIrq[i] = defaultIrq;
+ rtemsIrq[i].name = i;
+ }
+ /*
+ * Init initial Interrupt management config
+ */
+ initial_config.irqNb = BSP_IRQ_NUMBER;
+ initial_config.defaultEntry = defaultIrq;
+ initial_config.irqHdlTbl = rtemsIrq;
+ initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
+ initial_config.irqPrioTbl = irqPrioTable;
+
+ if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+ /*
+ * put something here that will show the failure...
+ */
+ BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+ }
+
+ /*
+ * We must connect the raw irq handler for the two
+ * expected interrupt sources : decrementer and external interrupts.
+ */
+ vectorDesc.exceptIndex = ASM_DEC_VECTOR;
+ vectorDesc.hdl.vector = ASM_DEC_VECTOR;
+ vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code;
+ vectorDesc.hdl.raw_hdl_size = (unsigned) decrementer_exception_vector_prolog_code_size;
+ vectorDesc.on = nop_func;
+ vectorDesc.off = nop_func;
+ vectorDesc.isOn = connected;
+ if (!mpc60x_set_exception (&vectorDesc)) {
+ BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
+ }
+ vectorDesc.exceptIndex = ASM_EXT_VECTOR;
+ vectorDesc.hdl.vector = ASM_EXT_VECTOR;
+ vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code;
+ vectorDesc.hdl.raw_hdl_size = (unsigned) external_exception_vector_prolog_code_size;
+ if (!mpc60x_set_exception (&vectorDesc)) {
+ BSP_panic("Unable to initialize RTEMS external raw exception\n");
+ }
+#ifdef TRACE_IRQ_INIT
+ printk("RTEMS IRQ management is now operationnal\n");
+#endif
+}
+
diff --git a/c/src/lib/libbsp/powerpc/psim/start/start.S b/c/src/lib/libbsp/powerpc/psim/start/start.S
index 118144c546..2b4a3c980c 100644
--- a/c/src/lib/libbsp/powerpc/psim/start/start.S
+++ b/c/src/lib/libbsp/powerpc/psim/start/start.S
@@ -17,6 +17,9 @@
* $Id$
*/
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/io.h>
#include "ppc-asm.h"
.file "startsim.s"
@@ -53,9 +56,14 @@ FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
.Lptr:
.long .LCTOC1-.Laddr
+ .globl __rtems_entry_point
+ .type __rtems_entry_point,@function
+__rtems_entry_point:
+#if 1
.globl _start
.type _start,@function
_start:
+#endif
bl .Laddr /* get current address */
.Laddr:
mflr r4 /* real address of .Laddr */
@@ -100,6 +108,7 @@ _start:
la r5,environ@l(r5) /* environp */
li r4, 0 /* argv */
li r3, 0 /* argc */
+
/* Let her rip */
bl FUNC_NAME(boot_card)
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
index 87403907e4..582b116ca9 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
@@ -16,11 +16,31 @@
#include <string.h>
#include <fcntl.h>
-
#include <bsp.h>
+#include <bsp/irq.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/bspIo.h>
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+SPR_RW(SPRG0)
+SPR_RW(SPRG1)
+
+
+extern unsigned long __rtems_end[];
+
+void initialize_exceptions(void);
+
+/* On psim, each click of the decrementer register corresponds
+ * to 1 instruction. By setting this to 100, we are indicating
+ * that we are assuming it can execute 100 instructions per
+ * microsecond. This corresponds to sustaining 1 instruction
+ * per cycle at 100 Mhz. Whether this is a good guess or not
+ * is anyone's guess.
+ */
+
+extern int PSIM_INSTRUCTIONS_PER_MICROSECOND;
/*
* The original table from the application and our copy of it with
@@ -29,9 +49,7 @@
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
-
rtems_cpu_table Cpu_table;
-uint32_t bsp_isr_level;
/*
* Tells us where to put the workspace in case remote debugger is present.
@@ -42,6 +60,17 @@ extern uint32_t rdb_start;
#endif
/*
+ * PCI Bus Frequency
+ */
+ unsigned int BSP_bus_frequency;
+ /*
+ * * Time base divisior (how many tick for 1 second).
+ * */
+ unsigned int BSP_time_base_divisor;
+
+
+
+/*
* Use the shared implementations of the following routines
*/
@@ -49,6 +78,25 @@ void bsp_postdriver_hook(void);
void bsp_libc_init( void *, uint32_t, int );
/*
+ * system init stack and soft ir stack size
+ */
+#define INIT_STACK_SIZE 0x1000
+#define INTR_STACK_SIZE CONFIGURE_INTERRUPT_STACK_MEMORY
+
+
+void BSP_panic(char *s)
+{
+ printk("%s PANIC %s\n",_RTEMS_version, s);
+ __asm__ __volatile ("sc");
+}
+
+void _BSP_Fatal_error(unsigned int v)
+{
+ printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
+ __asm__ __volatile ("sc");
+}
+
+/*
* bsp_pretasking_hook
*
* BSP pretasking hook. Called just before drivers are initialized.
@@ -84,16 +132,14 @@ void bsp_pretasking_hook(void)
void bsp_start( void )
{
- unsigned char *work_space_start;
+ unsigned char *work_space_start;
+ register uint32_t intrStack;
+ register uint32_t *intrStackPtr;
-#if 0
/*
- * Set MSR to show vectors at 0 XXX
+ * Note we can not get CPU identification dynamically, so force current_ppc_cpu.
*/
- _CPU_MSR_Value( msr_value );
- msr_value &= ~PPC_MSR_EP;
- _CPU_MSR_SET( msr_value );
-#endif
+ current_ppc_cpu = PPC_PSIM;
/*
* Set up our hooks
@@ -118,11 +164,14 @@ void bsp_start( void )
Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
+ BSP_bus_frequency = (unsigned int)&PSIM_INSTRUCTIONS_PER_MICROSECOND;
+ BSP_time_base_divisor = 1;
+
/*
- * The monitor likes the exception table to be at 0x0.
+ * The simulator likes the exception table to be at 0xfff00000.
*/
- Cpu_table.exceptions_in_RAM = TRUE;
+ Cpu_table.exceptions_in_RAM = FALSE;
BSP_Configuration.work_space_size += 1024;
@@ -136,4 +185,36 @@ void bsp_start( void )
BSP_Configuration.work_space_start = work_space_start;
+ /*
+ * Initialize the interrupt related settings
+ * SPRG1 = software managed IRQ stack
+ *
+ * This could be done latter (e.g in IRQ_INIT) but it helps to understand
+ * some settings below...
+ */
+ intrStack = ((uint32_t) __rtems_end) +
+ INIT_STACK_SIZE + INTR_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE;
+
+ /* make sure it's properly aligned */
+ intrStack &= ~(CPU_STACK_ALIGNMENT-1);
+
+ /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
+ intrStackPtr = (uint32_t*) intrStack;
+ *intrStackPtr = 0;
+
+ _write_SPRG1(intrStack);
+
+ /* signal them that we have fixed PR288 - eventually, this should go away */
+ _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
+
+ /*
+ * Initialize default raw exception hanlders. See vectors/vectors_init.c
+ */
+ initialize_exceptions();
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
}
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/linkcmds b/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
index e16a2450ce..bf5384ba5c 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
+++ b/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
@@ -16,7 +16,7 @@ OUTPUT_ARCH(powerpc)
ENTRY(_start)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
-PROVIDE (PSIM_INSTRUCTIONS_PER_MICROSECOND = 100);
+PROVIDE (PSIM_INSTRUCTIONS_PER_MICROSECOND = 10000); /* 100); */
PROVIDE (CPU_PPC_CLICKS_PER_MS = 16667);
MEMORY
{
@@ -26,35 +26,55 @@ MEMORY
SECTIONS
{
- .vectors 0xFFF00100 :
+ .entry_point_section :
{
- *(.vectors)
- } >EPROM
+ *(.entry_point_section)
+ } > EPROM
/* Read-only sections, merged into text segment: */
/* . = 0x40000 + SIZEOF_HEADERS; */
. = 0x4000;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .rela.text : { *(.rela.text) }
- .rela.data : { *(.rela.data) }
- .rela.rodata : { *(.rela.rodata) }
- .rela.got : { *(.rela.got) }
- .rela.got1 : { *(.rela.got1) }
- .rela.got2 : { *(.rela.got2) }
- .rela.ctors : { *(.rela.ctors) }
- .rela.dtors : { *(.rela.dtors) }
- .rela.init : { *(.rela.init) }
- .rela.fini : { *(.rela.fini) }
- .rela.bss : { *(.rela.bss) }
- .rela.plt : { *(.rela.plt) }
- .rela.sdata : { *(.rela.sdata2) }
- .rela.sbss : { *(.rela.sbss2) }
- .rela.sdata2 : { *(.rela.sdata2) }
- .rela.sbss2 : { *(.rela.sbss2) }
- .plt : { *(.plt) }
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
+ .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
+ .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
+ .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
+ .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
+ .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
+ .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
+ .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
.text :
{
*(.text)
@@ -74,17 +94,27 @@ SECTIONS
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} >RAM
- .init : { _init = .; __init = .; *(.init) } >RAM
- .fini : { _fini = .; __fini = .; *(.fini) } >RAM
+ .init :
+ {
+ KEEP (*(.init))
+ } >RAM =0
+ .fini :
+ {
+ _fini = .;
+ KEEP (*(.fini))
+ } >RAM =0
.rodata : { *(.rodata*) *(.gnu.linkonce.r*) } >RAM
.rodata1 : { *(.rodata1) } >RAM
+ PROVIDE (__FRAME_BEGIN__ = .);
.eh_frame : { *.(eh_frame) } >RAM
+ PROVIDE (__FRAME_END__ = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >RAM
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >RAM
PROVIDE (__SBSS2_END__ = .);
+ /* .eh_frame_hdr : { *(.eh_frame_hdr) } >RAM */
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
@@ -135,6 +165,8 @@ SECTIONS
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
+ .jcr : { KEEP (*(.jcr)) } > RAM
+
PROVIDE (__GOT_START__ = .);
PROVIDE (_GOT_START_ = .);
s.got = .;
@@ -155,9 +187,8 @@ SECTIONS
.sbss :
{
PROVIDE (__sbss_start = .);
- *(.sbss)
- *(.scommon)
- *(.gnu.linkonce.sb.*)
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
PROVIDE (__sbss_end = .);
} >RAM
PROVIDE (__SBSS_END__ = .);
@@ -166,10 +197,11 @@ SECTIONS
{
PROVIDE (__bss_start = .);
*(.dynbss)
- *(.bss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
} >RAM
. = ALIGN(8) + 0x8000;
+ __rtems_end = . ;
PROVIDE(__stack = .);
PROVIDE(_end = .);
PROVIDE(end = .);
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/setvec.c b/c/src/lib/libbsp/powerpc/psim/startup/setvec.c
deleted file mode 100644
index 21503ac17f..0000000000
--- a/c/src/lib/libbsp/powerpc/psim/startup/setvec.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* 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
- *
- * 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/libbsp/no_cpu/no_bsp/startup/setvec.c:
- *
- * COPYRIGHT (c) 1989-1999.
- * 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.rtems.com/license/LICENSE.
- *
- * $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;
-
- rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr );
-
- return previous_isr;
-}
diff --git a/c/src/lib/libbsp/powerpc/psim/timer/timer.c b/c/src/lib/libbsp/powerpc/psim/timer/timer.c
deleted file mode 100644
index a1412b2d0b..0000000000
--- a/c/src/lib/libbsp/powerpc/psim/timer/timer.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file implements a benchmark timer using the PPC decrement register.
- *
- * COPYRIGHT (c) 1989-2000.
- * On-Line Applications Research Corporation (OAR).
- *
- *
- * $Id$
- */
-
-#include <assert.h>
-
-#include <bsp.h>
-
-uint64_t Timer_driver_Start_time;
-
-rtems_boolean Timer_driver_Find_average_overhead;
-
-void Timer_initialize()
-{
- /*
- * Timer runs long and accurate enough not to require an interrupt.
- */
-
- Timer_driver_Start_time = PPC_Get_timebase_register();
-}
-
-#define AVG_OVERHEAD 24 /* It typically takes 24 instructions */
- /* to start/stop the timer. */
-#define LEAST_VALID 1 /* Don't trust a value lower than this */
- /* psim can count instructions. :) */
-
-int Read_timer()
-{
- uint64_t clicks;
- uint64_t total64;
- uint32_t total;
-
- /* approximately CLOCK_SPEED clicks per microsecond */
-
- clicks = PPC_Get_timebase_register();
-
- assert( clicks > Timer_driver_Start_time );
-
- total64 = clicks - Timer_driver_Start_time;
-
- assert( total64 <= 0xffffffff ); /* fits into a uint32_t */
-
- total = (uint32_t) total64;
-
- if ( Timer_driver_Find_average_overhead == 1 )
- return total; /* in one microsecond units */
-
- if ( total < LEAST_VALID )
- return 0; /* below timer resolution */
-
- return total - AVG_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/libbsp/powerpc/psim/tools/Makefile.am b/c/src/lib/libbsp/powerpc/psim/tools/Makefile.am
index 1908097507..0ba47df916 100644
--- a/c/src/lib/libbsp/powerpc/psim/tools/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/psim/tools/Makefile.am
@@ -22,6 +22,10 @@ $(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim: psim $(PROJECT_ROOT)/@RTEMS_BSP@/tests/$
$(INSTALL_SCRIPT) $< $(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim
TMPINSTALL_FILES += $(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim
+$(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim-gdb: psim $(PROJECT_ROOT)/@RTEMS_BSP@/tests/$(dirstamp)
+ $(INSTALL_SCRIPT) $< $(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim-gdb
+TMPINSTALL_FILES += $(PROJECT_ROOT)/@RTEMS_BSP@/tests/psim-gdb
+
$(PROJECT_ROOT)/@RTEMS_BSP@/tests/runtest: runtest $(PROJECT_ROOT)/@RTEMS_BSP@/tests/$(dirstamp)
$(INSTALL_SCRIPT) $< $(PROJECT_ROOT)/@RTEMS_BSP@/tests/runtest
TMPINSTALL_FILES += $(PROJECT_ROOT)/@RTEMS_BSP@/tests/runtest
diff --git a/c/src/lib/libbsp/powerpc/psim/tools/psim b/c/src/lib/libbsp/powerpc/psim/tools/psim
index 74dcf8bb49..99ca501e1b 100755
--- a/c/src/lib/libbsp/powerpc/psim/tools/psim
+++ b/c/src/lib/libbsp/powerpc/psim/tools/psim
@@ -36,8 +36,8 @@ echo "b _Internal_error_Occurred" >> ${GDB_FILE}
echo "b rtems_fatal_error_occurred" >> ${GDB_FILE}
echo "b __assert" >> ${GDB_FILE}
-RUN=powerpc-rtems-run
-GDB=powerpc-rtems-gdb
+RUN=powerpc-rtems4.7-run
+GDB=powerpc-rtems4.7-gdb
case $0 in
*gdb*)
diff --git a/c/src/lib/libbsp/powerpc/psim/vectors/vectors.S b/c/src/lib/libbsp/powerpc/psim/vectors/vectors.S
index 0d58bd38e4..65f65d30bb 100644
--- a/c/src/lib/libbsp/powerpc/psim/vectors/vectors.S
+++ b/c/src/lib/libbsp/powerpc/psim/vectors/vectors.S
@@ -1,122 +1,160 @@
-/* vectors.s 1.1 - 95/12/04
- *
- * This file contains the assembly code for the PowerPC
- * interrupt vectors for RTEMS.
- *
- * COPYRIGHT (c) 1989-1999.
- * 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.rtems.com/license/LICENSE.
- *
- * $Id$
- */
-
/*
- * 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.
+ * (c) 1999, Eric Valette valette@crf.canon.fr
*
- * 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.
+ * This file contains the assembly code for the PowerPC
+ * exception veneers for RTEMS.
*
- * 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 usually be 0x0000 or 0x0100.
+ * vectors.S,v 1.3.4.1 2003/02/20 21:48:25 joel Exp
*/
+
-#include <bsp.h>
-#include <rtems/asm.h>
-
-#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,0xFFF00000
- .set crit_vector,0xFFF00100
- .set mach_vector,0xFFF00200
- .set prot_vector,0xFFF00300
- .set ext_vector,0xFFF00500
- .set align_vector,0xFFF00600
- .set prog_vector,0xFFF00700
- .set dec_vector,0xFFF00900
- .set sys_vector,0xFFF00C00
- .set pit_vector,0xFFF01000
- .set fit_vector,0xFFF01010
- .set wadt_vector,0xFFF01020
- .set debug_vector,0xFFF02000
-
-/* Go to the right section */
-#if PPC_ASM == PPC_ASM_ELF
- .section .vectors,"awx",@progbits
-#elif PPC_ASM == PPC_ASM_XCOFF
- .csect .text[PR]
-#endif
-
- PUBLIC_VAR (__vectors)
-SYM (__vectors):
-
-/* Decrementer interrupt */
- .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)
-
- li r0, PPC_IRQ_DECREMENTER
- b PROC (_ISR_Handler)
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+#include <bsp/vectors.h>
+
+
+#define SYNC \
+ sync; \
+ isync
+
+ PUBLIC_VAR (__rtems_start)
+ .section .entry_point_section,"awx",@progbits
+/*
+ * Entry point information used by bootloader code
+ */
+SYM (__rtems_start):
+ .long __rtems_entry_point
+
+ /*
+ * end of special Entry point section
+ */
+ .text
+ .p2align 5
+
+PUBLIC_VAR(default_exception_vector_code_prolog)
+SYM (default_exception_vector_code_prolog):
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r3, GPR3_OFFSET(r1)
+ /* R2 should never change (EABI: pointer to .sdata2) - we
+ * save it nevertheless..
+ */
+ stw r2, GPR2_OFFSET(r1)
+ mflr r3
+ stw r3, EXC_LR_OFFSET(r1)
+ bl 0f
+0: /*
+ * r3 = exception vector entry point
+ * (256 * vector number) + few instructions
+ */
+ mflr r3
+ /*
+ * r3 = r3 >> 8 = vector
+ */
+ srwi r3,r3,8
+ ba push_normalized_frame
+
+ PUBLIC_VAR (default_exception_vector_code_prolog_size)
+
+ default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog
+
+ .p2align 5
+PUBLIC_VAR (push_normalized_frame)
+SYM (push_normalized_frame):
+ stw r3, EXCEPTION_NUMBER_OFFSET(r1)
+ stw r0, GPR0_OFFSET(r1)
+ mfsrr0 r3
+ stw r3, SRR0_FRAME_OFFSET(r1)
+ mfsrr1 r3
+ stw r3, SRR1_FRAME_OFFSET(r1)
+ /*
+ * Save general purpose registers
+ * Already saved in prolog : R1, R2, R3, LR.
+ * Saved a few line above : R0
+ *
+ * Manual says that "stmw" instruction may be slower than
+ * series of individual "stw" but who cares about performance
+ * for the DEFAULT exception handler?
+ */
+ stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */
+
+ mfcr r31
+ stw r31, EXC_CR_OFFSET(r1)
+ mfctr r30
+ stw r30, EXC_CTR_OFFSET(r1)
+ mfxer r28
+ stw r28, EXC_XER_OFFSET(r1)
+ mfmsr r28
+ stw r28, EXC_MSR_OFFSET(r1)
+ mfdar r28
+ stw r28, EXC_DAR_OFFSET(r1)
+ /*
+ * compute SP at exception entry
+ */
+ addi r3, r1, EXCEPTION_FRAME_END
+ /*
+ * store it at the right place
+ */
+ stw r3, GPR1_OFFSET(r1)
+ /*
+ * Enable data and instruction address translation, exception nesting
+ */
+ mfmsr r3
+ ori r3,r3, MSR_RI /* | MSR_IR | MSR_DR */
+ mtmsr r3
+ SYNC
+
+ /*
+ * Call C exception handler
+ */
+ /*
+ * store the execption frame address in r3 (first param)
+ */
+ addi r3, r1, 0x8
+ /*
+ * globalExceptHdl(r3)
+ */
+ addis r4, 0, globalExceptHdl@ha
+ lwz r5, globalExceptHdl@l(r4)
+ mtlr r5
+ blrl
+ /*
+ * Restore registers status
+ */
+ lwz r31, EXC_CR_OFFSET(r1)
+ mtcr r31
+ lwz r30, EXC_CTR_OFFSET(r1)
+ mtctr r30
+ lwz r29, EXC_LR_OFFSET(r1)
+ mtlr r29
+ lwz r28, EXC_XER_OFFSET(r1)
+ mtxer r28
+
+ lmw r4, GPR4_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ /*
+ * Disable data and instruction translation. Make path non recoverable...
+ */
+ mfmsr r3
+ xori r3, r3, MSR_RI | MSR_IR | MSR_DR
+ mtmsr r3
+ SYNC
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r3, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r3
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r3
+
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
diff --git a/c/src/lib/libbsp/powerpc/psim/wrapup/Makefile.am b/c/src/lib/libbsp/powerpc/psim/wrapup/Makefile.am
index 655c018a52..b47fa7a63f 100644
--- a/c/src/lib/libbsp/powerpc/psim/wrapup/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/psim/wrapup/Makefile.am
@@ -7,9 +7,18 @@ include $(top_srcdir)/../../../../automake/compile.am
EXTRA_LIBRARIES = ../libbsp.a
CLEANFILES = ../libbsp.a
___libbsp_a_SOURCES =
-___libbsp_a_LIBADD = ../startup$(LIB_VARIANT).rel ../clock$(LIB_VARIANT).rel \
- ../console$(LIB_VARIANT).rel ../timer$(LIB_VARIANT).rel \
+___libbsp_a_LIBADD = ../startup$(LIB_VARIANT).rel ../pclock$(LIB_VARIANT).rel \
+ ../console$(LIB_VARIANT).rel ../irq$(LIB_VARIANT).rel \
../vectors$(LIB_VARIANT).rel
+___libbsp_a_LIBADD += \
+ ../../../../libcpu/@RTEMS_CPU@/shared/cpuIdent$(LIB_VARIANT).rel \
+ ../../../../libcpu/@RTEMS_CPU@/shared/stack$(LIB_VARIANT).rel \
+ ../@exceptions@/rtems-cpu$(LIB_VARIANT).rel \
+ ../../../../libcpu/$(RTEMS_CPU)/mpc6xx/clock$(LIB_VARIANT).rel \
+ ../../../../libcpu/$(RTEMS_CPU)/mpc6xx/exceptions$(LIB_VARIANT).rel \
+ ../../../../libcpu/$(RTEMS_CPU)/mpc6xx/mmu$(LIB_VARIANT).rel \
+ ../../../../libcpu/$(RTEMS_CPU)/mpc6xx/timer$(LIB_VARIANT).rel
+
if HAS_MP
___libbsp_a_LIBADD += ../shmsupp$(LIB_VARIANT).rel
endif