[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.1

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: /*
        !            31:  * interrupt.c - interrupt handling routines for GBA
        !            32:  */
        !            33:
        !            34: #include <kernel.h>
        !            35: #include <irq.h>
        !            36: #include <locore.h>
        !            37:
        !            38: /* Interrupt hook vector */
        !            39: #define IRQ_VECTOR     *(uint32_t *)0x3007ffc
        !            40:
        !            41: /* Registers for interrupt control unit - enable/flag/master */
        !            42: #define ICU_IE         (*(volatile uint16_t *)0x4000200)
        !            43: #define ICU_IF         (*(volatile uint16_t *)0x4000202)
        !            44: #define ICU_IME                (*(volatile uint16_t *)0x4000208)
        !            45:
        !            46: /* ICU_IE */
        !            47: #define IRQ_VALID      0x3fff
        !            48:
        !            49: /* ICU_IME */
        !            50: #define IRQ_OFF                0
        !            51: #define IRQ_ON         1
        !            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 */
        !            66: static uint16_t mask_table[NIPLS];     /* Level -> mask */
        !            67:
        !            68: /*
        !            69:  * Set mask for current ipl
        !            70:  */
        !            71: #define update_mask()  ICU_IE = mask_table[irq_level]
        !            72:
        !            73: /*
        !            74:  * Unmask interrupt in PIC for specified irq.
        !            75:  * The interrupt mask table is also updated.
        !            76:  * Assumed CPU interrupt is disabled in caller.
        !            77:  */
        !            78: void
        !            79: interrupt_unmask(int vector, int level)
        !            80: {
        !            81:        int i;
        !            82:        uint16_t unmask = (uint16_t)1 << vector;
        !            83:
        !            84:        ipl_table[vector] = level;
        !            85:        /*
        !            86:         * Unmask target interrupt for all
        !            87:         * lower interrupt levels.
        !            88:         */
        !            89:        for (i = 0; i < level; i++)
        !            90:                mask_table[i] |= unmask;
        !            91:        update_mask();
        !            92: }
        !            93:
        !            94: /*
        !            95:  * Mask interrupt in PIC for specified irq.
        !            96:  * Interrupt must be disabled when this routine is called.
        !            97:  */
        !            98: void
        !            99: interrupt_mask(int vector)
        !           100: {
        !           101:        int i, level;
        !           102:        u_int mask = (uint16_t)~(1 << vector);
        !           103:
        !           104:        level = ipl_table[vector];
        !           105:        for (i = 0; i < level; i++)
        !           106:                mask_table[i] &= mask;
        !           107:        ipl_table[vector] = IPL_NONE;
        !           108:        update_mask();
        !           109: }
        !           110:
        !           111: /*
        !           112:  * Setup interrupt mode.
        !           113:  * Select whether an interrupt trigger is edge or level.
        !           114:  */
        !           115: void
        !           116: interrupt_setup(int vector, int mode)
        !           117: {
        !           118:        /* nop */
        !           119: }
        !           120:
        !           121: /*
        !           122:  * Dispatch interrupt
        !           123:  *
        !           124:  */
        !           125: void
        !           126: interrupt_dispatch(int vector)
        !           127: {
        !           128:        int old_ipl;
        !           129:
        !           130:        /* Save & update interrupt level */
        !           131:        old_ipl = irq_level;
        !           132:        irq_level = ipl_table[vector];
        !           133:        update_mask();
        !           134:
        !           135:        /* Send acknowledge to ICU for this irq */
        !           136:        ICU_IF = (uint16_t)(1 << vector);
        !           137:
        !           138:        /* Allow another interrupt that has higher priority */
        !           139:        interrupt_enable();
        !           140:
        !           141:        /* Dispatch interrupt */
        !           142:        irq_handler(vector);
        !           143:
        !           144:        interrupt_disable();
        !           145:
        !           146:        /* Restore interrupt level */
        !           147:        irq_level = old_ipl;
        !           148:        update_mask();
        !           149: }
        !           150:
        !           151: /*
        !           152:  * Common interrupt handler.
        !           153:  */
        !           154: void
        !           155: interrupt_handler(void)
        !           156: {
        !           157:        uint16_t bits;
        !           158:        int vector;
        !           159:
        !           160:        bits = ICU_IF;
        !           161: retry:
        !           162:        for (vector = 0; vector < NIRQS; vector++) {
        !           163:                if (bits & (uint16_t)(1 << vector))
        !           164:                        break;
        !           165:        }
        !           166:        if (vector == NIRQS)
        !           167:                goto out;
        !           168:
        !           169:        interrupt_dispatch(vector);
        !           170:
        !           171:        /*
        !           172:         * Multiple interrupts can be fired in case of GBA.
        !           173:         * So, we have to check the interrupt status, again.
        !           174:         */
        !           175:        bits = ICU_IF;
        !           176:        if (bits & IRQ_VALID)
        !           177:                goto retry;
        !           178: out:
        !           179:        return;
        !           180: }
        !           181:
        !           182: /*
        !           183:  * Initialize interrupt controllers.
        !           184:  * All interrupts will be masked off.
        !           185:  */
        !           186: void
        !           187: interrupt_init(void)
        !           188: {
        !           189:        int i;
        !           190:
        !           191:        irq_level = IPL_NONE;
        !           192:
        !           193:        for (i = 0; i < NIRQS; i++)
        !           194:                ipl_table[i] = IPL_NONE;
        !           195:
        !           196:        for (i = 0; i < NIPLS; i++)
        !           197:                mask_table[i] = 0;
        !           198:
        !           199:        ICU_IME = IRQ_OFF;
        !           200:        IRQ_VECTOR = (uint32_t)interrupt_entry; /* Interrupt hook address */
        !           201:        ICU_IE = 0;                     /* Mask all interrupts */
        !           202:        ICU_IME = IRQ_ON;
        !           203: }

CVSweb