[BACK]Return to interrupt.c CVS log [TXT][DIR] Up to [local] / prex-old / sys / arch / arm / cats

Annotation of prex-old/sys/arch/arm/cats/interrupt.c, Revision 1.2

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
1.2     ! nbrk       31:  * interrupt.c - interrupt handling routines for StrongARM-110 INTC.
1.1       nbrk       32:  */
                     33:
                     34: #include <kernel.h>
                     35: #include <irq.h>
                     36: #include <locore.h>
                     37:
1.2     ! nbrk       38: /* Registers for interrupt control unit */
        !            39: #define SAIC_BASE      0x90050000
        !            40: #define  SAIC_ICIP     0
        !            41: #define  SAIC_ICMR     0x04
        !            42: #define  SAIC_ICLR     0x08
        !            43: #define  SAIC_ICFP     0x10
        !            44: #define  SAIC_ICPR     0x20
        !            45: #define  SAIC_ICCR     0x0c
1.1       nbrk       46:
1.2     ! nbrk       47: /*
        !            48:  * Interrupt line routing (CPU IRQ/FIQ)
        !            49:  */
        !            50: #define IMODE_CPUIRQ   0
        !            51: #define IMODE_CPUFIQ   1
1.1       nbrk       52:
                     53: /*
                     54:  * Interrupt priority level
                     55:  *
                     56:  * Each interrupt has its logical priority level, with 0 being the highest
                     57:  * priority. While some ISR is running, all lower priority interrupts
                     58:  * are masked off.
                     59:  */
                     60: volatile int irq_level;
                     61:
                     62: /*
                     63:  * Interrupt mapping table
                     64:  */
                     65: static int ipl_table[NIRQS];           /* Vector -> level */
1.2     ! nbrk       66: static uint32_t mask_table[NIPLS];     /* Level -> mask */
        !            67:
        !            68: void   saic_updatemask(uint32_t mask);
        !            69: void   saic_routeto(int intrno, int irqfiq);
1.1       nbrk       70:
                     71: /*
                     72:  * Set mask for current ipl
                     73:  */
1.2     ! nbrk       74: #define interrupt_updatemask() saic_updatemask(mask_table[irq_level]);
        !            75:
        !            76: /*
        !            77:  * Write new mask to Mask Register.
        !            78:  */
        !            79: void
        !            80: saic_updatemask(uint32_t mask)
        !            81: {
        !            82:        /* XXX */
        !            83:        *(volatile uint32_t *)(SAIC_BASE + SAIC_ICMR) = mask;
        !            84: }
        !            85:
        !            86: /*
        !            87:  * Interrupt line routing to IRQ/FIQ.
        !            88:  */
        !            89: void
        !            90: saic_routeto(int intrno, int irqfiq)
        !            91: {
        !            92:        uint32_t bits;
        !            93:
        !            94:
        !            95:        bits = *(volatile uint32_t *)(SAIC_BASE + SAIC_ICLR);
        !            96:
        !            97:        switch(irqfiq) {
        !            98:                case IMODE_CPUIRQ:
        !            99:                        bits &= ~(1 << intrno);
        !           100:                        break;
        !           101:
        !           102:                case IMODE_CPUFIQ:
        !           103:                        bits |= 1 << intrno;
        !           104:                        break;
        !           105:
        !           106:                default:
        !           107:                        panic("saic_routeto: bogus irqfiq %u for intr %u", irqfiq, intrno);
        !           108:                        /* NOTREACHED */
        !           109:        }
        !           110: }
1.1       nbrk      111:
                    112: /*
                    113:  * Unmask interrupt in PIC for specified irq.
                    114:  * The interrupt mask table is also updated.
                    115:  * Assumed CPU interrupt is disabled in caller.
                    116:  */
                    117: void
                    118: interrupt_unmask(int vector, int level)
                    119: {
                    120:        int i;
1.2     ! nbrk      121:        uint32_t unmask = 1 << vector;
1.1       nbrk      122:
                    123:        ipl_table[vector] = level;
                    124:        /*
                    125:         * Unmask target interrupt for all
                    126:         * lower interrupt levels.
                    127:         */
                    128:        for (i = 0; i < level; i++)
                    129:                mask_table[i] |= unmask;
1.2     ! nbrk      130:
        !           131:        interrupt_updatemask();
1.1       nbrk      132: }
                    133:
                    134: /*
                    135:  * Mask interrupt in PIC for specified irq.
                    136:  * Interrupt must be disabled when this routine is called.
                    137:  */
                    138: void
                    139: interrupt_mask(int vector)
                    140: {
                    141:        int i, level;
1.2     ! nbrk      142:        uint32_t mask = (uint32_t)~(1 << vector);
1.1       nbrk      143:
                    144:        level = ipl_table[vector];
                    145:        for (i = 0; i < level; i++)
                    146:                mask_table[i] &= mask;
1.2     ! nbrk      147:
1.1       nbrk      148:        ipl_table[vector] = IPL_NONE;
1.2     ! nbrk      149:
        !           150:        interrupt_updatemask();
1.1       nbrk      151: }
                    152:
                    153: /*
                    154:  * Setup interrupt mode.
                    155:  * Select whether an interrupt trigger is edge or level.
                    156:  */
                    157: void
                    158: interrupt_setup(int vector, int mode)
                    159: {
                    160:        /* nop */
                    161: }
                    162:
                    163: /*
                    164:  * Dispatch interrupt
                    165:  *
                    166:  */
                    167: void
                    168: interrupt_dispatch(int vector)
                    169: {
                    170:        int old_ipl;
                    171:
1.2     ! nbrk      172:        printk("interrupt_dispatch()\n");
        !           173:
1.1       nbrk      174:        /* Save & update interrupt level */
                    175:        old_ipl = irq_level;
                    176:        irq_level = ipl_table[vector];
1.2     ! nbrk      177:        interrupt_updatemask();
1.1       nbrk      178:
                    179:        /* Allow another interrupt that has higher priority */
                    180:        interrupt_enable();
                    181:
                    182:        /* Dispatch interrupt */
                    183:        irq_handler(vector);
                    184:
                    185:        interrupt_disable();
                    186:
                    187:        /* Restore interrupt level */
                    188:        irq_level = old_ipl;
1.2     ! nbrk      189:        interrupt_updatemask();
1.1       nbrk      190: }
                    191:
                    192: /*
                    193:  * Common interrupt handler.
1.2     ! nbrk      194:  * Our task is to scan active pending intrs and dispatch them.
1.1       nbrk      195:  */
                    196: void
                    197: interrupt_handler(void)
                    198: {
1.2     ! nbrk      199:        uint32_t bits;
1.1       nbrk      200:        int vector;
                    201:
1.2     ! nbrk      202:
        !           203:        /* XXX we use only IRQs for now, so don't count FIQs */
        !           204:        bits = *(volatile uint32_t *)(SAIC_BASE + SAIC_ICIP);
        !           205:
        !           206:        /* dispatch all pending interrupts */
1.1       nbrk      207:        for (vector = 0; vector < NIRQS; vector++) {
1.2     ! nbrk      208:                if (bits & (1 << vector))
        !           209:                        interrupt_dispatch(vector);
        !           210:
        !           211:                /* XXX pending intr clears within interrupting device */
1.1       nbrk      212:        }
                    213:
                    214: }
                    215:
                    216: /*
                    217:  * Initialize interrupt controllers.
1.2     ! nbrk      218:  * All interrupts will be masked off and routed to CPU IRQ line.
1.1       nbrk      219:  */
                    220: void
                    221: interrupt_init(void)
                    222: {
                    223:        int i;
                    224:
1.2     ! nbrk      225:        interrupt_disable();
        !           226:
1.1       nbrk      227:        irq_level = IPL_NONE;
                    228:
                    229:        for (i = 0; i < NIRQS; i++)
                    230:                ipl_table[i] = IPL_NONE;
                    231:
                    232:        for (i = 0; i < NIPLS; i++)
                    233:                mask_table[i] = 0;
                    234:
1.2     ! nbrk      235:        /*
        !           236:         * XXX route all Interrupt Controller interrupts to CPU IRQ line.
        !           237:         */
        !           238:        for (i = 0; i < NIRQS; i++)
        !           239:                saic_routeto(i, IMODE_CPUIRQ);
        !           240:
        !           241:        interrupt_updatemask();
        !           242:
        !           243:        interrupt_enable();
1.1       nbrk      244: }

CVSweb