diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c b/c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c deleted file mode 100644 index eb36cc2a80..0000000000 --- a/c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * 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 the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * Acknowledgement May 2004, to Till Straumann <strauman@slac.stanford.edu> - * for some inputs. - * - * Copyright 2003, 2004, 2005, 2007 Shuchen Kate Feng <feng1@bnl.gov>, - * NSLS, Brookhaven National Laboratory. All rights reserved. - * - * 1) Used GT_GPP_Value register instead of the GT_GPP_Interrupt_Cause - * register to monitor the cause of the level sensitive interrupts. - * (Copyright : NDA item) - * 2) The implementation of picPrioTable[] is an original work by the - * author to optimize the software IRQ priority scheduling because - * Discovery controller does not provide H/W IRQ priority schedule. - * It ensures the fastest/faster interrupt service to the - * highest/higher priority IRQ, if pendig. - * 3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER() - * - */ - -#include <inttypes.h> -#include <stdio.h> -#include <rtems/system.h> -#include <bsp.h> -#include <bsp/irq.h> -#include <rtems/score/thread.h> -#include <rtems/rtems/intr.h> -#include <libcpu/io.h> -#include <libcpu/byteorder.h> -#include <bsp/vectors.h> - -#include <rtems/bspIo.h> /* for printk */ -#include "bsp/gtreg.h" - -#define HI_INT_CAUSE 0x40000000 - -#define MAX_IRQ_LOOP 20 - -/* #define DEBUG_IRQ*/ - -/* - * 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 the table given - * in BSP_rtems_irq_mngt_set(); - * CAUTION : this table is accessed directly by interrupt routine - * prologue. - */ -static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER]; - -/* - * location used to store initial tables used for interrupt - * management.BSP copy of the configuration - */ -static rtems_irq_global_settings BSP_config; -static rtems_irq_connect_data* rtems_hdl_tbl; - -/* - * default handler connected on each irq after bsp initialization - * (locally cached copy) - */ -void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1; - - -static volatile unsigned *BSP_irqMask_reg[3]; -static volatile unsigned *BSP_irqCause_reg[3]; -static volatile unsigned BSP_irqMask_cache[3]={0,0,0}; - -static int picPrioTblPtr=0; -static unsigned int GPPIrqInTbl=0; -static unsigned long long MainIrqInTbl=0; - -/* - * The software developers are forbidden to setup picPrioTable[], - * as it is a powerful engine for the BSP to find the pending - * highest priority IRQ at run time. It ensures the fastest/faster - * interrupt service to the highest/higher priority IRQ, if pendig. - * - * The picPrioTable[96] is updated dynamically at run time - * based on the priority levels set at BSPirqPrioTable[96], - * while the BSP_enable_irq_at_pic(), and BSP_disable_irq_at_pic() - * commands are invoked. - * - * The picPrioTable[96] lists the enabled CPU main and GPP external interrupt - * numbers [0 (lowest)- 95 (highest)] starting from the highest priority - * one to the lowest priority one. The highest priority interrupt is - * located at picPrioTable[0], and the lowest priority interrupt is located - * at picPrioTable[picPrioTblPtr-1]. - * - * - */ -#define DynamicIsrTable -#ifdef DynamicIsrTable -/* BitNums for Main Interrupt Lo/High Cause, -1 means invalid bit */ -static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1 }; -#else -static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={ - 80, 84, 76, 77, 32, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1 }; -#endif - -/* - * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ - */ -static inline int is_pic_irq(const rtems_irq_number irqLine) -{ - return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) & - ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET) - ); -} - -/* - * Check if IRQ is a Porcessor IRQ - */ -static inline int is_processor_irq(const rtems_irq_number irqLine) -{ - return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) & - ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) - ); -} - -/* - * ------------------------ RTEMS Irq helper functions ---------------- - */ - -/* - * Caution : this function assumes the variable "BSP_config" - * is already set and that the tables it contains are still valid - * and accessible. - */ -static void compute_pic_masks_from_prio(void) -{ - int i,j, k, isGppMain; - unsigned long long irq_prio_mask=0; - - /* - * Always mask at least current interrupt to prevent re-entrance - */ - for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) { - switch(i) { - case BSP_MAIN_GPP7_0_IRQ: - case BSP_MAIN_GPP15_8_IRQ: - case BSP_MAIN_GPP23_16_IRQ: - case BSP_MAIN_GPP31_24_IRQ: - for (k=0; k< 3; k++) - BSP_irq_prio_mask_tbl[k][i]=0; - - irq_prio_mask =0; - isGppMain =1; - break; - default : - isGppMain =0; - irq_prio_mask = (unsigned long long) (1LLU << i); - break; - } - if ( isGppMain) continue; - for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) { - /* - * Mask interrupts at PIC level that have a lower priority - * or <Till Straumann> a equal priority. - */ - if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j]) - irq_prio_mask |= (unsigned long long)(1LLU << j); - } - - - BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff; - BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff; -#if 0 - printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i], - BSP_irq_prio_mask_tbl[0][i]); -#endif - - BSP_irq_prio_mask_tbl[2][i] = 1<<i; - /* Compute for the GPP priority interrupt mask */ - for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) { - if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j]) - BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET); - } -#if 0 - printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]); -#endif - } -} - -static void UpdateMainIrqTbl(int irqNum) -{ - int i=0, j, shifted=0; - - switch (irqNum) { - case BSP_MAIN_GPP7_0_IRQ: - case BSP_MAIN_GPP15_8_IRQ: - case BSP_MAIN_GPP23_16_IRQ: - case BSP_MAIN_GPP31_24_IRQ: - return; /* Do nothing, let GPP take care of it */ - break; - } -#ifdef SHOW_MORE_INIT_SETTINGS - unsigned long val2, val1; -#endif - - /* If entry not in table*/ - if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) && - (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) || - ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) && - (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))) - { - while ( picPrioTable[i]!=-1) { - if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) { - /* all other lower priority entries shifted right */ - for (j=picPrioTblPtr;j>i; j--) { - picPrioTable[j]=picPrioTable[j-1]; - } - picPrioTable[i]=irqNum; - shifted=1; - break; - } - i++; - } - if (!shifted) picPrioTable[picPrioTblPtr] =irqNum; - - if (irqNum >BSP_MICH_IRQ_MAX_OFFSET) - GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)); - else - MainIrqInTbl |= (unsigned long long)(1LLU << irqNum); - picPrioTblPtr++; - } -#ifdef SHOW_MORE_INIT_SETTINGS - val2 = (MainIrqInTbl>>32) & 0xffffffff; - val1 = MainIrqInTbl&0xffffffff; - printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1); - BSP_printPicIsrTbl(); -#endif - -} - - -static void CleanMainIrqTbl(int irqNum) -{ - int i, j; - - switch (irqNum) { - case BSP_MAIN_GPP7_0_IRQ: - case BSP_MAIN_GPP15_8_IRQ: - case BSP_MAIN_GPP23_16_IRQ: - case BSP_MAIN_GPP31_24_IRQ: - return; /* Do nothing, let GPP take care of it */ - break; - } - if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) && - ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) || - ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) && - (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))) - { /* If entry in table*/ - for (i=0; i<64; i++) { - if (picPrioTable[i]==irqNum) {/*remove it from the entry */ - /* all other lower priority entries shifted left */ - for (j=i;j<picPrioTblPtr; j++) { - picPrioTable[j]=picPrioTable[j+1]; - } - if (irqNum >BSP_MICH_IRQ_MAX_OFFSET) - GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)); - else - MainIrqInTbl &= ~(1LLU << irqNum); - picPrioTblPtr--; - break; - } - } - } -} - -void BSP_enable_irq_at_pic(const rtems_irq_number irqNum) -{ - unsigned bitNum, regNum; - unsigned int level; - - if ( !is_pic_irq(irqNum) ) - return; - - bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32; - regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5; - - rtems_interrupt_disable(level); - -#ifdef DynamicIsrTable - UpdateMainIrqTbl((int) irqNum); -#endif - BSP_irqMask_cache[regNum] |= (1 << bitNum); - - out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]); - while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]); - - rtems_interrupt_enable(level); -} - -int BSP_disable_irq_at_pic(const rtems_irq_number irqNum) -{ - int rval; - unsigned bitNum, regNum; - unsigned int level; - - if ( ! is_pic_irq(irqNum) ) - return -1; - - bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32; - regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5; - - rtems_interrupt_disable(level); - -#ifdef DynamicIsrTable - CleanMainIrqTbl((int) irqNum); -#endif - - rval = BSP_irqMask_cache[regNum] & (1<<bitNum); - - BSP_irqMask_cache[regNum] &= ~(1 << bitNum); - - out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]); - while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]); - - rtems_interrupt_enable(level); - - return rval ? 1 : 0; -} - -/* Use shared/irq : 2008 */ -int BSP_setup_the_pic(rtems_irq_global_settings* config) -{ - int i; - - BSP_config = *config; - default_rtems_hdl = config->defaultEntry.hdl; - rtems_hdl_tbl = config->irqHdlTbl; - - /* Get ready for discovery BSP */ - BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO); - BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI); - BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO); - BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI); - BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask); - BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value); - - /* Page 401, Table 598: - * Comm Unit Arbiter Control register : - * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0). - * MOTload default is set as level sensitive(1). Set it agin to make sure. - */ - out_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl, - (in_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl)| (1<<10))); - -#if 0 - printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[0]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[0])); - printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[1]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[1])); - printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[2]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[2])); -#endif - - /* Initialize the interrupt related registers */ - for (i=0; i<3; i++) { - out_le32((volatile uint32_t *)BSP_irqCause_reg[i], 0); - out_le32((volatile uint32_t *)BSP_irqMask_reg[i], 0); - } - in_le32((volatile uint32_t *)BSP_irqMask_reg[2]); - compute_pic_masks_from_prio(); - -#if 0 - printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[0]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[0])); - printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[1]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[1])); - printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n", - in_le32((volatile uint32_t *)BSP_irqMask_reg[2]), - in_le32((volatile uint32_t *)BSP_irqCause_reg[2])); -#endif - - /* - * - */ - for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) { - if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) { - BSP_enable_irq_at_pic(i); - BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]); - } - else { - BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]); - BSP_disable_irq_at_pic(i); - } - } - for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++) - BSP_enable_irq_at_pic(i); - - return(1); -} - -/* - * High level IRQ handler called from shared_raw_irq_code_entry - */ -int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum) -{ - unsigned long irqCause[3]={0, 0,0}; - unsigned oldMask[3]={0,0,0}; - int loop=0, i=0, j; - int irq=0, group=0; - - if (excNum == ASM_DEC_VECTOR) { - bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl); - return 0; - } - - for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j]; - for (j=0; j<3; j++) irqCause[j] = in_le32((volatile uint32_t *)BSP_irqCause_reg[j]) & in_le32((volatile uint32_t *)BSP_irqMask_reg[j]); - - while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP)) - { - if (irqCause[group= irq/32] & ( 1<<(irq % 32))) { - for (j=0; j<3; j++) - BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]); - - out_le32((volatile uint32_t *)BSP_irqMask_reg[0], BSP_irqMask_cache[0]); - out_le32((volatile uint32_t *)BSP_irqMask_reg[1], BSP_irqMask_cache[1]); - out_le32((volatile uint32_t *)BSP_irqMask_reg[2], BSP_irqMask_cache[2]); - in_le32((volatile uint32_t *)BSP_irqMask_reg[2]); - - bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl); - - for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j]; - - out_le32((volatile uint32_t *)BSP_irqMask_reg[0], oldMask[0]); - out_le32((volatile uint32_t *)BSP_irqMask_reg[1], oldMask[1]); - out_le32((volatile uint32_t *)BSP_irqMask_reg[2], oldMask[2]); - in_le32((volatile uint32_t *)BSP_irqMask_reg[2]); - } - } - - return 0; -} - -/* Only print part of the entries for now */ -void BSP_printPicIsrTbl(void) -{ - int i; - - printf("picPrioTable[12]={ {irq# : "); - for (i=0; i<12; i++) - printf("%d,", picPrioTable[i]); - printf("}\n"); - - printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl); -} |