diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2010-11-15 10:55:02 +0000 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2010-11-15 10:55:02 +0000 |
commit | ddd5640ff64895e7d937bf69d8d8f8ffc507aad9 (patch) | |
tree | e05873b61dbe6b17b253c92f3d74dfbacb34aa9a /c/src/lib/libbsp/powerpc/gen5200/irq/irq.c | |
parent | 2010-11-12 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff) | |
download | rtems-ddd5640ff64895e7d937bf69d8d8f8ffc507aad9.tar.bz2 |
2010-11-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* make/custom/dp2.cfg, startup/linkcmds.dp2: New files.
* Makefile.am, preinstall.am: Reflect change above. Install
<bsp/utility.h>. Install BestComm header files.
* configure.ac: Changed BSP options.
* include/mpc5200.h: Added module structures and register defines.
* bestcomm/bestcomm_api.c, bestcomm/bestcomm_api.h,
bestcomm/bestcomm_glue.c, bestcomm/bestcomm_glue.h,
bestcomm/bestcomm_priv.h, bestcomm/load_task.c,
bestcomm/tasksetup_bdtable.c, bestcomm/task_api/bestcomm_cntrl.h: C++
compatibility. Use special heap to manage the SRAM region. Use
interrupt extension API. Fixed warnings.
* console/console.c: Fixed console registration. Fixed warnings.
Added GPS module registration.
* ide/pcmcia_ide.h: Fixed clock value macros.
* ide/pcmcia_ide.c: Update for BestComm API changes.
DP2 specific initialization. Removed zero loop in PIO receive
function.
* include/bsp.h: Added DP2 variant. Removed obsolete defines.
* include/mscan-base.h, mscan/mscan-base.c: Use volatile qualifier.
Format.
* irq/irq.c: Fixed peripheral interrupt handling.
* network_5200/network.c: Update for BestComm API changes.
* start/start.S: U-Boot fixes.
* startup/cpuinit.c: Enable write-back cache strategy. Added special
memory regions.
* startup/linkcmds.brs5l: Fixed memory size.
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen5200/irq/irq.c | 249 |
1 files changed, 43 insertions, 206 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c index f0a15d0ae8..0dc80bf523 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c +++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c @@ -480,19 +480,38 @@ void BSP_IRQ_Benchmarking_Report( void) } #endif +static void dispatch(uint32_t irq, uint32_t offset, volatile uint32_t *maskreg) +{ + #if (ALLOW_IRQ_NESTING == 1) + uint32_t msr; + #endif + + uint32_t mask = *maskreg; + + irq += offset; + + *maskreg = mask | irqMaskTable [irq]; + + #if (ALLOW_IRQ_NESTING == 1) + msr = ppc_external_exceptions_enable(); + #endif + + bsp_interrupt_handler_dispatch(irq); + + #if (ALLOW_IRQ_NESTING == 1) + ppc_external_exceptions_disable(msr); + #endif + + *maskreg = mask; +} + /* * High level IRQ handler called from shared_raw_irq_code_entry */ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) { - register unsigned int irq; - register unsigned int pmce; - register unsigned int crit_pri_main_mask, - per_mask; - -#if (ALLOW_IRQ_NESTING == 1) - uint32_t msr; -#endif + uint32_t irq; + uint32_t pmce; #if (BENCHMARK_IRQ_PROCESSING == 1) uint64_t start, @@ -518,133 +537,8 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) break; - case ASM_60X_SYSMGMT_VECTOR: - - /* get the content of main interrupt status register */ - pmce = mpc5200.pmce; - - /* main interrupts may be routed to SMI, see bit SMI/INT select - * bit in main int. priorities - */ - while (CHK_MSE_STICKY( pmce)) { - - /* check for main interrupt sources (hirarchical order) - * -> LO_int indicates peripheral sources - */ - if (CHK_MSE_STICKY( pmce)) { - /* get source of main interrupt */ - irq = MSE_SOURCE( pmce); - switch (irq) { - - /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: - * slice timer 2 is always routed to SMI) - */ - case 0: /* slice timer 2 */ - case 1: - case 2: - case 3: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - - /* add proper offset for main interrupts in - * the siu handler array - */ - irq += BSP_MAIN_IRQ_LOWEST_OFFSET; - - /* save original mask and disable all lower - * priorized main interrupts - */ - crit_pri_main_mask = mpc5200.crit_pri_main_mask; - mpc5200.crit_pri_main_mask |= irqMaskTable [irq]; - -#if (ALLOW_IRQ_NESTING == 1) - /* enable interrupt nesting */ - msr = ppc_external_exceptions_enable(); -#endif - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( irq); - -#if (ALLOW_IRQ_NESTING == 1) - /* disable interrupt nesting */ - ppc_external_exceptions_disable( msr); -#endif - - /* restore original interrupt mask */ - mpc5200.crit_pri_main_mask = crit_pri_main_mask; - - break; - - /* peripheral LO_int interrupt source detected */ - case 4: - - /* check for valid peripheral interrupt source */ - if (CHK_PSE_STICKY( pmce)) { - /* get source of peripheral interrupt */ - irq = PSE_SOURCE( pmce); - - /* add proper offset for peripheral interrupts - * in the siu handler array - */ - irq += BSP_PER_IRQ_LOWEST_OFFSET; - - /* save original mask and disable all lower - * priorized main interrupts - */ - per_mask = mpc5200.per_mask; - mpc5200.per_mask |= irqMaskTable [irq]; - -#if (ALLOW_IRQ_NESTING == 1) - /* enable interrupt nesting */ - msr = ppc_external_exceptions_enable(); -#endif - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( irq); - -#if (ALLOW_IRQ_NESTING == 1) - /* disable interrupt nesting */ - ppc_external_exceptions_disable( msr); -#endif - - /* restore original interrupt mask */ - mpc5200.per_mask = per_mask; - - /* force re-evaluation of peripheral interrupts */ - CLR_PSE_STICKY( mpc5200.pmce); - } else { - /* this case may not occur: no valid peripheral - * interrupt source - */ - printk( "No valid peripheral LO_int interrupt source\n"); - } - break; - /* error: unknown interrupt source */ - default: - printk( "Unknown peripheral LO_int interrupt source\n"); - break; - } - - /* force re-evaluation of main interrupts */ - CLR_MSE_STICKY( mpc5200.pmce); - } - - /* get the content of main interrupt status register */ - pmce = mpc5200.pmce; - } - break; - case ASM_EXT_VECTOR: + case ASM_60X_SYSMGMT_VECTOR: /* get the content of main interrupt status register */ pmce = mpc5200.pmce; @@ -682,30 +576,7 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) /* get source of peripheral interrupt */ irq = PSE_SOURCE( pmce); - /* add proper offset for peripheral interrupts in the - * siu handler array */ - irq += BSP_PER_IRQ_LOWEST_OFFSET; - - /* save original mask and disable all lower - * priorized main interrupts */ - per_mask = mpc5200.per_mask; - mpc5200.per_mask |= irqMaskTable [irq]; - -#if (ALLOW_IRQ_NESTING == 1) - /* enable interrupt nesting */ - msr = ppc_external_exceptions_enable(); -#endif - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( irq); - -#if (ALLOW_IRQ_NESTING == 1) - /* disable interrupt nesting */ - ppc_external_exceptions_disable( msr); -#endif - - /* restore original interrupt mask */ - mpc5200.per_mask = per_mask; + dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask); /* force re-evaluation of peripheral interrupts */ CLR_PSE_STICKY( mpc5200.pmce); @@ -734,6 +605,7 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer * 2 is always routed to SMI) */ + case 0: case 1: case 2: case 3: @@ -749,30 +621,7 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) case 14: case 15: case 16: - /* add proper offset for main interrupts in the siu - * handler array */ - irq += BSP_MAIN_IRQ_LOWEST_OFFSET; - - /* save original mask and disable all lower priorized - * main interrupts*/ - crit_pri_main_mask = mpc5200.crit_pri_main_mask; - mpc5200.crit_pri_main_mask |= irqMaskTable [irq]; - -#if (ALLOW_IRQ_NESTING == 1) - /* enable interrupt nesting */ - msr = ppc_external_exceptions_enable(); -#endif - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( irq); - -#if (ALLOW_IRQ_NESTING == 1) - /* disable interrupt nesting */ - ppc_external_exceptions_disable( msr); -#endif - - /* restore original interrupt mask */ - mpc5200.crit_pri_main_mask = crit_pri_main_mask; + dispatch(irq, BSP_MAIN_IRQ_LOWEST_OFFSET, &mpc5200.crit_pri_main_mask); break; /* peripheral LO_int interrupt source detected */ @@ -782,30 +631,7 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) /* get source of peripheral interrupt */ irq = PSE_SOURCE( pmce); - /* add proper offset for peripheral interrupts in the siu - * handler array */ - irq += BSP_PER_IRQ_LOWEST_OFFSET; - - /* save original mask and disable all lower priorized main - * interrupts */ - per_mask = mpc5200.per_mask; - mpc5200.per_mask |= irqMaskTable [irq]; - -#if (ALLOW_IRQ_NESTING == 1) - /* enable interrupt nesting */ - msr = ppc_external_exceptions_enable(); -#endif - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( irq); - -#if (ALLOW_IRQ_NESTING == 1) - /* disable interrupt nesting */ - ppc_external_exceptions_disable( msr); -#endif - - /* restore original interrupt mask */ - mpc5200.per_mask = per_mask; + dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask); /* force re-evaluation of peripheral interrupts */ CLR_PSE_STICKY( mpc5200.pmce); @@ -824,6 +650,17 @@ int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned excNum) /* force re-evaluation of main interrupts */ CLR_MSE_STICKY( mpc5200.pmce); } + + if (CHK_PSE_STICKY( pmce)) { + /* get source of peripheral interrupt */ + irq = PSE_SOURCE( pmce); + + dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask); + + /* force re-evaluation of peripheral interrupts */ + CLR_PSE_STICKY( mpc5200.pmce); + } + /* get the content of main interrupt status register */ pmce = mpc5200.pmce; } |