Annotation of qemu/hw/etraxfs_pic.c, revision 1.1.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.