Annotation of qemu/hw/etraxfs_pic.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU ETRAX Interrupt Controller.
        !             3:  *
        !             4:  * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             7:  * of this software and associated documentation files (the "Software"), to deal
        !             8:  * in the Software without restriction, including without limitation the rights
        !             9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            10:  * copies of the Software, and to permit persons to whom the Software is
        !            11:  * furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included in
        !            14:  * all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            22:  * THE SOFTWARE.
        !            23:  */
        !            24: 
        !            25: #include <stdio.h>
        !            26: #include "hw.h"
        !            27: #include "etraxfs.h"
        !            28: 
        !            29: #define D(x)
        !            30: 
        !            31: struct fs_pic_state_t
        !            32: {
        !            33:        CPUState *env;
        !            34: 
        !            35:        uint32_t rw_mask;
        !            36:        /* Active interrupt lines.  */
        !            37:        uint32_t r_vect;
        !            38:        /* Active lines, gated through the mask.  */
        !            39:        uint32_t r_masked_vect;
        !            40:        uint32_t r_nmi;
        !            41:        uint32_t r_guru;
        !            42: };
        !            43: 
        !            44: static void pic_update(struct fs_pic_state_t *fs)
        !            45: {      
        !            46:        CPUState *env = fs->env;
        !            47:        int i;
        !            48:        uint32_t vector = 0;
        !            49: 
        !            50:        fs->r_masked_vect = fs->r_vect & fs->rw_mask;
        !            51: 
        !            52:        /* The ETRAX interrupt controller signals interrupts to teh core
        !            53:           through an interrupt request wire and an irq vector bus. If 
        !            54:           multiple interrupts are simultaneously active it chooses vector 
        !            55:           0x30 and lets the sw choose the priorities.  */
        !            56:        if (fs->r_masked_vect) {
        !            57:                uint32_t mv = fs->r_masked_vect;
        !            58:                for (i = 0; i < 31; i++) {
        !            59:                        if (mv & 1) {
        !            60:                                vector = 0x31 + i;
        !            61:                                /* Check for multiple interrupts.  */
        !            62:                                if (mv > 1)
        !            63:                                        vector = 0x30;
        !            64:                                break;
        !            65:                        }
        !            66:                        mv >>= 1;
        !            67:                }
        !            68:                if (vector) {
        !            69:                        env->interrupt_vector = vector;
        !            70:                        D(printf("%s vector=%x\n", __func__, vector));
        !            71:                        cpu_interrupt(env, CPU_INTERRUPT_HARD);
        !            72:                }
        !            73:        } else {
        !            74:                env->interrupt_vector = 0;
        !            75:                cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
        !            76:                D(printf("%s reset irqs\n", __func__));
        !            77:        }
        !            78: }
        !            79: 
        !            80: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
        !            81: {
        !            82:        struct fs_pic_state_t *fs = opaque;
        !            83:        uint32_t rval;
        !            84: 
        !            85:        switch (addr)
        !            86:        {
        !            87:                case 0x0: 
        !            88:                        rval = fs->rw_mask;
        !            89:                        break;
        !            90:                case 0x4: 
        !            91:                        rval = fs->r_vect;
        !            92:                        break;
        !            93:                case 0x8: 
        !            94:                        rval = fs->r_masked_vect;
        !            95:                        break;
        !            96:                case 0xc: 
        !            97:                        rval = fs->r_nmi;
        !            98:                        break;
        !            99:                case 0x10: 
        !           100:                        rval = fs->r_guru;
        !           101:                        break;
        !           102:                default:
        !           103:                        cpu_abort(fs->env, "invalid PIC register.\n");
        !           104:                        break;
        !           105: 
        !           106:        }
        !           107:        D(printf("%s %x=%x\n", __func__, addr, rval));
        !           108:        return rval;
        !           109: }
        !           110: 
        !           111: static void
        !           112: pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
        !           113: {
        !           114:        struct fs_pic_state_t *fs = opaque;
        !           115:        D(printf("%s addr=%x val=%x\n", __func__, addr, value));
        !           116:        switch (addr) 
        !           117:        {
        !           118:                case 0x0: 
        !           119:                        fs->rw_mask = value;
        !           120:                        pic_update(fs);
        !           121:                        break;
        !           122:                default:
        !           123:                        cpu_abort(fs->env, "invalid PIC register.\n");
        !           124:                        break;
        !           125:        }
        !           126: }
        !           127: 
        !           128: static CPUReadMemoryFunc *pic_read[] = {
        !           129:        NULL, NULL,
        !           130:        &pic_readl,
        !           131: };
        !           132: 
        !           133: static CPUWriteMemoryFunc *pic_write[] = {
        !           134:        NULL, NULL,
        !           135:        &pic_writel,
        !           136: };
        !           137: 
        !           138: void pic_info(void)
        !           139: {
        !           140: }
        !           141: 
        !           142: void irq_info(void)
        !           143: {
        !           144: }
        !           145: 
        !           146: static void irq_handler(void *opaque, int irq, int level)
        !           147: {      
        !           148:        struct fs_pic_state_t *fs = (void *)opaque;
        !           149: 
        !           150:        D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n", 
        !           151:                 __func__, irq, level,
        !           152:                 fs->rw_mask, fs->r_vect, fs->r_masked_vect));
        !           153: 
        !           154:        irq -= 1;
        !           155:        fs->r_vect &= ~(1 << irq);
        !           156:        fs->r_vect |= (!!level << irq);
        !           157: 
        !           158:        pic_update(fs);
        !           159: }
        !           160: 
        !           161: static void nmi_handler(void *opaque, int irq, int level)
        !           162: {      
        !           163:        struct fs_pic_state_t *fs = (void *)opaque;
        !           164:        CPUState *env = fs->env;
        !           165:        uint32_t mask;
        !           166: 
        !           167:        mask = 1 << irq;
        !           168:        if (level)
        !           169:                fs->r_nmi |= mask;
        !           170:        else
        !           171:                fs->r_nmi &= ~mask;
        !           172: 
        !           173:        if (fs->r_nmi)
        !           174:                cpu_interrupt(env, CPU_INTERRUPT_NMI);
        !           175:        else
        !           176:                cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
        !           177: }
        !           178: 
        !           179: static void guru_handler(void *opaque, int irq, int level)
        !           180: {      
        !           181:        struct fs_pic_state_t *fs = (void *)opaque;
        !           182:        CPUState *env = fs->env;
        !           183:        cpu_abort(env, "%s unsupported exception\n", __func__);
        !           184: 
        !           185: }
        !           186: 
        !           187: struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
        !           188: {
        !           189:        struct fs_pic_state_t *fs = NULL;
        !           190:        struct etraxfs_pic *pic = NULL;
        !           191:        int intr_vect_regs;
        !           192: 
        !           193:        pic = qemu_mallocz(sizeof *pic);
        !           194:        pic->internal = fs = qemu_mallocz(sizeof *fs);
        !           195: 
        !           196:        fs->env = env;
        !           197:        pic->irq = qemu_allocate_irqs(irq_handler, fs, 30);
        !           198:        pic->nmi = qemu_allocate_irqs(nmi_handler, fs, 2);
        !           199:        pic->guru = qemu_allocate_irqs(guru_handler, fs, 1);
        !           200: 
        !           201:        intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
        !           202:        cpu_register_physical_memory(base, 0x14, intr_vect_regs);
        !           203: 
        !           204:        return pic;
        !           205: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.