Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:50

0001 /**
0002  *  @file
0003  *  
0004  *  Au1x00 Interrupt Vectoring
0005  */
0006 
0007 /*
0008  *  Copyright (c) 2005 by Cogent Computer Systems
0009  *  Written by Jay Monkman <jtm@lopingdog.com>
0010  *
0011  *  The license and distribution terms for this file may be
0012  *  found in the file LICENSE in this distribution or at
0013  *  http://www.rtems.org/license/LICENSE.
0014  */
0015 
0016 #include <rtems.h>
0017 #include <stdlib.h>
0018 #include <libcpu/au1x00.h>
0019 #include <libcpu/isr_entries.h>
0020 #include <rtems/irq.h>
0021 #include <bsp/irq.h>
0022 #include <bsp/irq-generic.h>
0023 
0024 static void call_vectored_isr(CPU_Interrupt_frame *, uint32_t , void *);
0025 
0026 #include <rtems/bspIo.h>  /* for printk */
0027 
0028 void mips_vector_isr_handlers( CPU_Interrupt_frame *frame )
0029 {
0030   unsigned int sr;
0031   unsigned int cause;
0032 
0033   mips_get_sr( sr );
0034   mips_get_cause( cause );
0035 
0036   cause &= (sr & SR_IMASK);
0037   cause >>= CAUSE_IPSHIFT;
0038 
0039   /* count/compare interrupt */
0040   if ( cause & 0x80 ) {
0041       unsigned long zero = 0;
0042       /*
0043        * I don't see a good way to disable the compare
0044        * interrupt, so let's just ignore it.
0045        */
0046       __asm__ volatile ("mtc0 %0, $11\n" :: "r" (zero));
0047   }
0048 
0049   /* Performance counter */
0050   if ( cause & 0x40 ) {
0051       bsp_interrupt_handler_dispatch(AU1X00_IRQ_PERF);
0052   }
0053 
0054   /* Interrupt controller 0 */
0055   if ( cause & 0x0c ) {
0056       call_vectored_isr(frame, cause, (void *)AU1X00_IC0_ADDR);
0057   }
0058 
0059   /* Interrupt controller 1 */
0060   if ( cause & 0x30 ) {
0061       call_vectored_isr(frame, cause, (void *)AU1X00_IC1_ADDR);
0062   }
0063 
0064   /* SW[0] */
0065   if ( cause & 0x01 )
0066       bsp_interrupt_handler_dispatch( AU1X00_IRQ_SW0 );
0067 
0068   /* SW[1] */
0069   if ( cause & 0x02 )
0070       bsp_interrupt_handler_dispatch( AU1X00_IRQ_SW1 );
0071 }
0072 
0073 void mips_default_isr( int vector )
0074 {
0075   unsigned int sr;
0076   unsigned int cause;
0077 
0078   mips_get_sr( sr );
0079   mips_get_cause( cause );
0080 
0081   printk( "Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",
0082       vector, cause, sr );
0083   rtems_fatal_error_occurred(1);
0084 }
0085 
0086 static void call_vectored_isr(
0087     CPU_Interrupt_frame *frame,
0088     uint32_t cause,
0089     void *ctrlr
0090     )
0091 {
0092     uint32_t src;
0093     uint32_t mask;
0094     int index;
0095 
0096     /* get mask register */
0097     mask = AU1X00_IC_MASKRD(ctrlr);
0098 
0099     /* check request 0 */
0100     src = AU1X00_IC_REQ0INT(ctrlr);
0101     src = src & mask;
0102     index = 0;
0103     while (src) {
0104         /* check LSB */
0105         if (src & 1) {
0106             /* clear rising/falling edge detects */
0107             AU1X00_IC_RISINGCLR(ctrlr) = (1 << index);
0108             AU1X00_IC_FALLINGCLR(ctrlr) = (1 << index);
0109             au_sync();
0110             bsp_interrupt_handler_dispatch(AU1X00_IRQ_IC0_BASE + index);
0111         }
0112         index ++;
0113 
0114         /* shift, and make sure MSB is clear */
0115         src = (src >> 1) & 0x7fffffff;
0116     }
0117 
0118     /* check request 1 */
0119     src = AU1X00_IC_REQ1INT(ctrlr);
0120     src = src & mask;
0121     index = 0;
0122     while (src) {
0123         /* check LSB */
0124         if (src & 1) {
0125             /* clear rising/falling edge detects */
0126             AU1X00_IC_RISINGCLR(ctrlr) = (1 << index);
0127             AU1X00_IC_FALLINGCLR(ctrlr) = (1 << index);
0128             au_sync();
0129             bsp_interrupt_handler_dispatch(AU1X00_IRQ_IC0_BASE + index);
0130         }
0131         index ++;
0132 
0133         /* shift, and make sure MSB is clear */
0134         src = (src >> 1) & 0x7fffffff;
0135     }
0136 }
0137 
0138 /* Generate a software interrupt */
0139 int assert_sw_irq(uint32_t irqnum)
0140 {
0141     uint32_t cause;
0142 
0143     if (irqnum <= 1) {
0144         mips_get_cause(cause);
0145         cause = cause | ((irqnum + 1) << CAUSE_IPSHIFT);
0146         mips_set_cause(cause);
0147 
0148         return irqnum;
0149     } else {
0150         return -1;
0151     }
0152 }
0153 
0154 /* Clear a software interrupt */
0155 int negate_sw_irq(uint32_t irqnum)
0156 {
0157     uint32_t cause;
0158 
0159     if (irqnum <= 1) {
0160         mips_get_cause(cause);
0161         cause = cause & ~((irqnum + 1) << CAUSE_IPSHIFT);
0162         mips_set_cause(cause);
0163 
0164         return irqnum;
0165     } else {
0166         return -1;
0167     }
0168 }