diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2001-10-22 14:46:02 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2001-10-22 14:46:02 +0000 |
commit | 5edbffe3f64131c582839e0bbd389fda5eeb407c (patch) | |
tree | 81ab7ce00a76f8f8cae955ef5fac8fb4cd9cc7f1 /c/src/lib/libbsp/powerpc/mpc8260ads/irq | |
parent | 2001-10-22 Joel Sherrill <joel@OARcorp.com> (diff) | |
download | rtems-5edbffe3f64131c582839e0bbd389fda5eeb407c.tar.bz2 |
01-10-22 Andy Dachs <a.dachs@sstl.co.uk>
* mpc8260ads added as new BSP. tm27 reported not to run
at this time.
* ChangeLog, Makefile.am, README, aclocal.m4, bsp_specs,
clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, configure.in,
console/Makefile.am, console/console.c, include/Makefile.am,
include/bsp.h, include/coverhd.h, irq/.cvsignore, irq/Makefile.am,
irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c,
network/Makefile.am, network/README, network/if_hdlcsubr.c,
network/if_hdlcsubr.h, network/network.c, start/Makefile.am,
start/start.S, startup/Makefile.am, startup/bspstart.c,
startup/cpuinit.c, startup/linkcmds, startup/setvec.c, times,
vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S,
vectors/vectors.h, vectors/vectors_init.c, wrapup/Makefile.am:
New files.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mpc8260ads/irq')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am | 46 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c | 453 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.h | 347 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S | 339 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c | 150 |
6 files changed, 1337 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am new file mode 100644 index 0000000000..4b5bc87fe4 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am @@ -0,0 +1,46 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +C_FILES = irq.c irq_init.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +H_FILES = irq.h + +S_FILES = irq_asm.S +S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +SORDID_HACK: + rm -f $(PROJECT_INCLUDE)/bsp/irq.h + +$(PROJECT_INCLUDE)/bsp: + $(mkinstalldirs) $@ + +$(PROJECT_INCLUDE)/bsp/%.h: %.h + $(INSTALL_DATA) $< $@ + +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp \ + $(H_FILES:%.h=$(PROJECT_INCLUDE)/bsp/%.h) + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + +all-local: SORDID_HACK $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(PGM) + +EXTRA_DIST = irq.c irq.h irq_asm.S irq_init.c + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c new file mode 100644 index 0000000000..75267e48be --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c @@ -0,0 +1,453 @@ +/* + * + * This file contains the implementation of the function described in irq.h + * + * Copyright (C) 1998, 1999 valette@crf.canon.fr + * + * Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk> + * Surrey Satellite Technology Limited, 2000 + * Nested exception handlers not working yet. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <rtems/score/thread.h> +#include <rtems/score/apiext.h> +#include <libcpu/raw_exception.h> +#include <bsp/vectors.h> +#include <libcpu/cpu.h> +/*#include <bsp/8xx_immap.h>*/ +#include <mpc8260.h> +/*#include <bsp/commproc.h>*/ + +/* + * 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 symbolic IRQ name is an CPM IRQ + */ +static inline int is_cpm_irq(const rtems_irq_symbolic_name irqLine) +{ + return (((int) irqLine <= BSP_CPM_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_CPM_IRQ_LOWEST_OFFSET) + ); +} + +/* + * Check if symbolic IRQ name is a Processor 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) + ); +} + + +/* + * bit in the SIU mask registers (PPC bit numbering) that should + * be set to enable the relevant interrupt + * + */ +const static unsigned int SIU_MaskBit[BSP_CPM_IRQ_NUMBER] = +{ + 63, 48, 49, 50, /* err, i2c, spi, rtt */ + 51, 52, 53, 54, /* smc1, smc2, idma1, idma2 */ + 55, 56, 57, 63, /* idma3, idma4, sdma, - */ + 59, 60, 61, 62, /* tmr1, tmr2, tmr3, tmr4 */ + 29, 30, 63, 17, /* pit, tmcnt, -, irq1 */ + 18, 19, 20, 21, /* irq2, irq3, irq4, irq5 */ + 22, 23, 63, 63, /* irq6, irq7, -, - */ + 63, 63, 63, 63, /* -, -, -, - */ + 32, 33, 34, 35, /* fcc1, fcc2, fcc3, - */ + 36, 37, 38, 39, /* mcc1, mcc2, -, - */ + 40, 41, 42, 43, /* scc1, scc2, scc3, scc4 */ + 44, 45, 46, 47, /* -, -, -, - */ + 0, 1, 2, 3, /* pc0, pc1, pc2, pc3 */ + 4, 5, 6, 7, /* pc4, pc5, pc6, pc7 */ + 8, 9, 10, 11, /* pc8, pc9, pc10, pc11 */ + 12, 13, 14, 15 /* pc12, pc13, pc14, pc15 */ +}; + +/* + * ------------------------ RTEMS Irq helper functions ---------------- + */ + +/* + * Caution : this function assumes the variable "internal_config" + * is already set and that the tables it contains are still valid + * and accessible. + */ +static void compute_SIU_IvectMask_from_prio () +{ + /* + * In theory this is feasible. No time to code it yet. See i386/shared/irq.c + * for an example based on 8259 controller mask. The actual masks defined + * correspond to the priorities defined for the SIU in irq_init.c. + */ +} + +/* + * 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; +} + +int BSP_irq_enable_at_cpm(const rtems_irq_symbolic_name irqLine) +{ + int cpm_irq_index; + + if (!is_cpm_irq(irqLine)) + return 1; + + cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET); + + + if( SIU_MaskBit[cpm_irq_index] < 32 ) + m8260.simr_h |= (0x80000000 >> SIU_MaskBit[cpm_irq_index]); + else + m8260.simr_l |= (0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32)); + + return 0; +} + +int BSP_irq_disable_at_cpm(const rtems_irq_symbolic_name irqLine) +{ + int cpm_irq_index; + + if (!is_cpm_irq(irqLine)) + return 1; + + cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET); + + if( SIU_MaskBit[cpm_irq_index] < 32 ) + m8260.simr_h &= ~(0x80000000 >> SIU_MaskBit[cpm_irq_index]); + else + m8260.simr_l &= ~(0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32)); + + + return 0; +} + +int BSP_irq_enabled_at_cpm(const rtems_irq_symbolic_name irqLine) +{ + int cpm_irq_index; + + if (!is_cpm_irq(irqLine)) + return 0; + + cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET); + + if( SIU_MaskBit[cpm_irq_index] < 32 ) + return m8260.simr_h & (0x80000000 >> SIU_MaskBit[cpm_irq_index]); + else + return m8260.simr_l & (0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32)); +} + + +/* + * ------------------------ 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( "not a valid intr\n" ) ; + 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. + */ + if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) { + printk( "Default handler not there\n" ); + return 0; + } + + _CPU_ISR_Disable(level); + + /* + * store the data provided by user + */ + rtems_hdl_tbl[irq->name] = *irq; + + if (is_cpm_irq(irq->name)) { + /* + * Enable interrupt at PIC level + */ + BSP_irq_enable_at_cpm (irq->name); + } + + + if (is_processor_irq(irq->name)) { + /* + * Should Enable exception at processor level but not needed. Will restore + * EE flags at the end of the routine anyway. + */ + } + /* + * Enable interrupt on device + */ + irq->on(irq); + + _CPU_ISR_Enable(level); + +/* + printk( "Enabled\n" ); +*/ + return 1; +} + + +int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq) +{ + if (!isValidInterrupt(irq->name)) { + return 0; + } + *irq = rtems_hdl_tbl[irq->name]; + return 1; +} + +int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) +{ + 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. + */ + if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { + return 0; + } + _CPU_ISR_Disable(level); + + if (is_cpm_irq(irq->name)) { + /* + * disable interrupt at PIC level + */ + BSP_irq_disable_at_cpm (irq->name); + } + + if (is_processor_irq(irq->name)) { + /* + * disable exception at processor level + */ + } + + /* + * Disable interrupt on device + */ + irq->off(irq); + + /* + * restore the default irq value + */ + rtems_hdl_tbl[irq->name] = default_rtems_entry; + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * ------------------------ RTEMS Global Irq Handler Mngt Routines ---------------- + */ + +int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) +{ + int i; + unsigned int level; + /* + * Store various code accelerators + */ + internal_config = config; + default_rtems_entry = config->defaultEntry; + rtems_hdl_tbl = config->irqHdlTbl; + + _CPU_ISR_Disable(level); + /* + * start with CPM IRQ + */ + for (i=BSP_CPM_IRQ_LOWEST_OFFSET; i < BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER ; i++) { + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + BSP_irq_enable_at_cpm (i); + rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); + } + else { + rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); + BSP_irq_disable_at_cpm (i); + } + } + + /* + * finish with Processor exceptions handled like IRQ + */ + for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) { + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); + } + else { + rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); + } + } + _CPU_ISR_Enable(level); + return 1; +} + +int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config) +{ + *config = internal_config; + return 0; +} + +#ifdef DISPATCH_HANDLER_STAT +volatile unsigned int maxLoop = 0; +#endif + +/* + * 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 int irq; +#if 0 + register unsigned oldMask; /* old siu pic masks */ +#endif + register unsigned msr; + register unsigned new_msr; +#ifdef DISPATCH_HANDLER_STAT + unsigned loopCounter; +#endif + + + + /* + * Handle decrementer interrupt + */ + if (excNum == ASM_DEC_VECTOR) { + +/* + _BSP_GPLED1_on(); +*/ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + rtems_hdl_tbl[BSP_DECREMENTER].hdl(); + + _CPU_MSR_SET(msr); + +/* + _BSP_GPLED1_off(); +*/ + return; + } + + /* + * Handle external interrupt generated by SIU on PPC core + */ +#ifdef DISPATCH_HANDLER_STAT + loopCounter = 0; +#endif + while (1) { + + if( ((m8260.sipnr_h & m8260.simr_h) | (m8260.sipnr_l & m8260.simr_l)) == 0 ) { +#ifdef DISPATCH_HANDLER_STAT + if (loopCounter > maxLoop) maxLoop = loopCounter; +#endif + break; + } + + irq = (m8260.sivec >> 26) + BSP_CPM_IRQ_LOWEST_OFFSET; + +/* + printk( "dispatching %d\n", irq ); +*/ + + /* Clear pending register */ + if( irq <= BSP_CPM_IRQ_MAX_OFFSET ) { + if( SIU_MaskBit[irq] < 32 ) + m8260.sipnr_h = (0x80000000 >> SIU_MaskBit[irq]); + else + m8260.sipnr_l = (0x80000000 >> (SIU_MaskBit[irq]-32)); + } + +/* + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); +*/ + rtems_hdl_tbl[irq].hdl(); +/* + _CPU_MSR_SET(msr); +*/ + + + +#if 0 + ppc_cached_irq_mask |= (oldMask & ~(SIU_IvectMask[irq])); + ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask; +#endif +#ifdef DISPATCH_HANDLER_STAT + ++ loopCounter; +#endif + } + + + + +} + + + +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/mpc8260ads/irq/irq.h b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.h new file mode 100644 index 0000000000..7f30ec4402 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.h @@ -0,0 +1,347 @@ +/* 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. + * + * Modified for mpc8260 by Andy Dachs <a.dachs@sstl.co.uk> + * Surrey Satellite Technology Limited + * The interrupt handling on the mpc8260 seems quite different from + * the 860 (I don't know the 860 well). Although some interrupts + * are routed via the CPM irq and some are direct to the SIU they all + * appear logically the same. Therefore I removed the distinction + * between SIU and CPM interrupts. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H +#define LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H + + +#define BSP_ASM_IRQ_VECTOR_BASE 0x0 + +#ifndef ASM + +/* +extern volatile unsigned int ppc_cached_irq_mask; +*/ + +/* + * Symblolic IRQ names and related definitions. + */ + +typedef enum { + /* Base vector for our SIU IRQ handlers. */ + BSP_SIU_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE, + + /* + * CPM IRQ handlers related definitions + * CAUTION : BSP_CPM_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE + */ + BSP_CPM_IRQ_NUMBER = 64, + BSP_CPM_IRQ_LOWEST_OFFSET = BSP_SIU_VECTOR_BASE, + BSP_CPM_IRQ_MAX_OFFSET = BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_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_CPM_IRQ_MAX_OFFSET + 1, + BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1, + /* + * Summary + */ + BSP_IRQ_NUMBER = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1, + BSP_LOWEST_OFFSET = BSP_CPM_IRQ_LOWEST_OFFSET, + BSP_MAX_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET, + + /* + * Some SIU IRQ symbolic name definition. Please note that + * INT IRQ are defined but a single one will be used to + * redirect all CPM interrupt. + * + * On the mpc8260 all this seems to be transparent. Although the + * CPM, PIT and TMCNT interrupt may well be the only interrupts routed + * to the SIU at the hardware level all of them appear as CPM interupts + * to software apart from the registers for setting priority. + * + * The MPC8260 User Manual seems shot through with inconsistencies + * about this whole area. + */ + + /* + * Some CPM IRQ symbolic name definition + */ + BSP_CPM_IRQ_ERROR = BSP_CPM_IRQ_LOWEST_OFFSET, + BSP_CPM_IRQ_I2C = BSP_CPM_IRQ_LOWEST_OFFSET + 1, + BSP_CPM_IRQ_SPI = BSP_CPM_IRQ_LOWEST_OFFSET + 2, + BSP_CPM_IRQ_RISC_TIMERS = BSP_CPM_IRQ_LOWEST_OFFSET + 3, + BSP_CPM_IRQ_SMC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 4, + BSP_CPM_IRQ_SMC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 5, + BSP_CPM_IRQ_IDMA1 = BSP_CPM_IRQ_LOWEST_OFFSET + 6, + BSP_CPM_IRQ_IDMA2 = BSP_CPM_IRQ_LOWEST_OFFSET + 7, + BSP_CPM_IRQ_IDMA3 = BSP_CPM_IRQ_LOWEST_OFFSET + 8, + BSP_CPM_IRQ_IDMA4 = BSP_CPM_IRQ_LOWEST_OFFSET + 9, + BSP_CPM_IRQ_SDMA = BSP_CPM_IRQ_LOWEST_OFFSET + 10, + + BSP_CPM_IRQ_TIMER_1 = BSP_CPM_IRQ_LOWEST_OFFSET + 12, + BSP_CPM_IRQ_TIMER_2 = BSP_CPM_IRQ_LOWEST_OFFSET + 13, + BSP_CPM_IRQ_TIMER_3 = BSP_CPM_IRQ_LOWEST_OFFSET + 14, + BSP_CPM_IRQ_TIMER_4 = BSP_CPM_IRQ_LOWEST_OFFSET + 15, + BSP_CPM_IRQ_TMCNT = BSP_CPM_IRQ_LOWEST_OFFSET + 16, + BSP_CPM_IRQ_PIT = BSP_CPM_IRQ_LOWEST_OFFSET + 17, + + BSP_CPM_IRQ_IRQ1 = BSP_CPM_IRQ_LOWEST_OFFSET + 19, + BSP_CPM_IRQ_IRQ2 = BSP_CPM_IRQ_LOWEST_OFFSET + 20, + BSP_CPM_IRQ_IRQ3 = BSP_CPM_IRQ_LOWEST_OFFSET + 21, + BSP_CPM_IRQ_IRQ4 = BSP_CPM_IRQ_LOWEST_OFFSET + 22, + BSP_CPM_IRQ_IRQ5 = BSP_CPM_IRQ_LOWEST_OFFSET + 23, + BSP_CPM_IRQ_IRQ6 = BSP_CPM_IRQ_LOWEST_OFFSET + 24, + BSP_CPM_IRQ_IRQ7 = BSP_CPM_IRQ_LOWEST_OFFSET + 25, + + BSP_CPM_IRQ_FCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 32, + BSP_CPM_IRQ_FCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 33, + BSP_CPM_IRQ_FCC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 34, + + BSP_CPM_IRQ_MCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 36, + BSP_CPM_IRQ_MCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 37, + + BSP_CPM_IRQ_SCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 40, + BSP_CPM_IRQ_SCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 41, + BSP_CPM_IRQ_SCC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 42, + BSP_CPM_IRQ_SCC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 43, + + BSP_CPM_IRQ_PC15 = BSP_CPM_IRQ_LOWEST_OFFSET + 48, + BSP_CPM_IRQ_PC14 = BSP_CPM_IRQ_LOWEST_OFFSET + 49, + BSP_CPM_IRQ_PC13 = BSP_CPM_IRQ_LOWEST_OFFSET + 50, + BSP_CPM_IRQ_PC12 = BSP_CPM_IRQ_LOWEST_OFFSET + 51, + BSP_CPM_IRQ_PC11 = BSP_CPM_IRQ_LOWEST_OFFSET + 52, + BSP_CPM_IRQ_PC10 = BSP_CPM_IRQ_LOWEST_OFFSET + 53, + BSP_CPM_IRQ_PC9 = BSP_CPM_IRQ_LOWEST_OFFSET + 54, + BSP_CPM_IRQ_PC8 = BSP_CPM_IRQ_LOWEST_OFFSET + 55, + BSP_CPM_IRQ_PC7 = BSP_CPM_IRQ_LOWEST_OFFSET + 56, + BSP_CPM_IRQ_PC6 = BSP_CPM_IRQ_LOWEST_OFFSET + 57, + BSP_CPM_IRQ_PC5 = BSP_CPM_IRQ_LOWEST_OFFSET + 58, + BSP_CPM_IRQ_PC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 59, + BSP_CPM_IRQ_PC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 60, + BSP_CPM_IRQ_PC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 61, + BSP_CPM_IRQ_PC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 62, + BSP_CPM_IRQ_PC0 = BSP_CPM_IRQ_LOWEST_OFFSET + 63, + + + /* + * Some Processor exception handled as rtems IRQ symbolic name definition + */ + BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET, + BSP_PERIODIC_TIMER = BSP_DECREMENTER + +}rtems_irq_symbolic_name; + +#define CPM_INTERRUPT + + +/* + * Type definition for RTEMS managed interrupts + */ +typedef unsigned char rtems_irq_prio; +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 SIU level and CPM 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 SIU and CPM 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; +} 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_SIU_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. ++--------------------------------------------------------------------------*/ +/* + * ------------------------ PPC CPM Mngt Routines ------- + */ + +/* + * function to disable a particular irq. 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_cpm (const rtems_irq_symbolic_name irqLine); +/* + * function to enable a particular irq. After calling + * this function, if the device asserts the interrupt line it will + * be propagated further to the processor + */ +int BSP_irq_enable_at_cpm (const rtems_irq_symbolic_name irqLine); +/* + * function to acknoledge a particular irq. 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_cpm (const rtems_irq_symbolic_name irqLine); +/* + * function to check if a particular irq is enabled. After calling + */ +int BSP_irq_enabled_at_cpm (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, + * 4) modify them to disable the current interrupt at SIU level (and may + * be others depending on software priorities) + * 5) aknowledge the SIU', + * 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 SIU 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*); +/* + * 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); +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S new file mode 100644 index 0000000000..3216e63e28 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S @@ -0,0 +1,339 @@ +/* + * 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.OARcorp.com/rtems/license.html. + * + * Modified to support the MCP750. + * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr + * + * + * $Id$ + */ + +#include <bsp/vectors.h> +#include <libcpu/cpu.h> +#include <libcpu/raw_exception.h> +#include <rtems/score/cpuopts.h> /* for PPC_HAS_FPU */ +#include "asm.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) + stw r2, GPR2_OFFSET(r1) + stw r3, GPR3_OFFSET(r1) + + mfsrr0 r0 + mfsrr1 r2 + mfmsr r3 + + stw r0, SRR0_FRAME_OFFSET(r1) + stw r2, SRR1_FRAME_OFFSET(r1) + + + /* + * 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_IR | MSR_DR |*/ MSR_FP +#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 + /* + * Get current nesting level in R2 + */ + mfspr r2, SPRG0 + /* + * Check if stack switch is necessary + */ + cmpwi r2,0 + bne nested + mfspr r1, SPRG1 + +nested: + /* + * Start Incrementing nesting level in R2 + */ + addi r2,r2,1 + /* + * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level + */ + lwz r6,_Thread_Dispatch_disable_level@l(r15) + /* + * store new nesting level in SPRG0 + */ + mtspr SPRG0, r2 + + 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 + */ + mfspr r2, SPRG0 + /* + * start decrementing _Thread_Dispatch_disable_level + */ + lwz r3,_Thread_Dispatch_disable_level@l(r15) + addi r2, r2, -1 /* Continue decrementing nesting level */ + addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */ + mtspr SPRG0, r2 /* End decrementing nesting level */ + 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 r2, r1, EXCEPTION_FRAME_END + /* + * store it at the right place + */ + stw r2, 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 r2, SRR0_FRAME_OFFSET(r1) + lwz r3, GPR3_OFFSET(r1) + lwz r0, GPR0_OFFSET(r1) + + mtsrr1 r4 + mtsrr0 r2 + lwz r4, GPR4_OFFSET(r1) + lwz r2, GPR2_OFFSET(r1) + addi r1,r1, EXCEPTION_FRAME_END + SYNC + rfi + diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c new file mode 100644 index 0000000000..166185eac5 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c @@ -0,0 +1,150 @@ +/* irq_init.c + * + * This file contains the implementation of rtems initialization + * related to interrupt handling. + * + * CopyRight (C) 2001 valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ +#include <bsp/irq.h> +#include <bsp.h> +#include <bspIo.h> +#include <libcpu/raw_exception.h> +/* +#include <bsp/8xx_immap.h> +#include <bsp/mbx.h> +#include <bsp/commproc.h> +*/ + +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(); + +extern void BSP_panic(char *s); +extern void _BSP_Fatal_error(unsigned int v); +/* +volatile unsigned int ppc_cached_irq_mask; +*/ + +/* + * 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 priorities for interrupt : + */ + /* + * CPM Interrupts + */ + 0, 45, 63, 44, 66, 68, 35, 39, 50, 62, 34, 0, 30, 40, 52, 58, + 2, 3, 0, 5, 15, 16, 17, 18, 49, 51, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 0, 11, 12, 0, 0, 20, 21, 22, 23, 0, 0, 0, 0, + 29, 31, 33, 37, 38, 41, 47, 48, 55, 56, 57, 60, 64, 65, 69, 70, + /* + * Processor exceptions handled as interrupts + */ + 0 +}; + + +/* + * Initialize CPM interrupt management + */ +void +BSP_CPM_irq_init(void) +{ + m8260.simr_l = 0; + m8260.simr_h = 0; + m8260.sipnr_l = 0xffffffff; + m8260.sipnr_h = 0xffffffff; + m8260.sicr = 0; + + /* + * Initialize the interrupt priorities. + */ + m8260.siprr = 0x05309770; /* reset value */ + m8260.scprr_h = 0x05309770; /* reset value */ + m8260.scprr_l = 0x05309770; /* reset value */ + +} + +void BSP_rtems_irq_mng_init(unsigned cpuId) +{ + rtems_raw_except_connect_data vectorDesc; + int i; + + BSP_CPM_irq_init(); + /* + * 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 (!mpc8xx_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 (!mpc8xx_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 +} + |