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

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: 
1.1.1.2 ! root       25: #include "sysbus.h"
1.1       root       26: #include "hw.h"
1.1.1.2 ! root       27: //#include "pc.h"
        !            28: //#include "etraxfs.h"
1.1       root       29: 
                     30: #define D(x)
                     31: 
1.1.1.2 ! root       32: #define R_RW_MASK   0
        !            33: #define R_R_VECT    1
        !            34: #define R_R_MASKED_VECT 2
        !            35: #define R_R_NMI     3
        !            36: #define R_R_GURU    4
        !            37: #define R_MAX       5
        !            38: 
        !            39: struct etrax_pic
        !            40: {
        !            41:     SysBusDevice busdev;
        !            42:     uint32_t *interrupt_vector;
        !            43:     qemu_irq parent_irq;
        !            44:     qemu_irq parent_nmi;
        !            45:     uint32_t regs[R_MAX];
1.1       root       46: };
                     47: 
1.1.1.2 ! root       48: static void pic_update(struct etrax_pic *fs)
        !            49: {   
        !            50:     uint32_t vector = 0;
        !            51:     int i;
        !            52: 
        !            53:     fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
        !            54: 
        !            55:     /* The ETRAX interrupt controller signals interrupts to teh core
        !            56:        through an interrupt request wire and an irq vector bus. If 
        !            57:        multiple interrupts are simultaneously active it chooses vector 
        !            58:        0x30 and lets the sw choose the priorities.  */
        !            59:     if (fs->regs[R_R_MASKED_VECT]) {
        !            60:         uint32_t mv = fs->regs[R_R_MASKED_VECT];
        !            61:         for (i = 0; i < 31; i++) {
        !            62:             if (mv & 1) {
        !            63:                 vector = 0x31 + i;
        !            64:                 /* Check for multiple interrupts.  */
        !            65:                 if (mv > 1)
        !            66:                     vector = 0x30;
        !            67:                 break;
        !            68:             }
        !            69:             mv >>= 1;
        !            70:         }
        !            71:     }
        !            72: 
        !            73:     if (fs->interrupt_vector) {
        !            74:         *fs->interrupt_vector = vector;
        !            75:     }
        !            76:     qemu_set_irq(fs->parent_irq, !!vector);
1.1       root       77: }
                     78: 
                     79: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
                     80: {
1.1.1.2 ! root       81:     struct etrax_pic *fs = opaque;
        !            82:     uint32_t rval;
1.1       root       83: 
1.1.1.2 ! root       84:     rval = fs->regs[addr >> 2];
        !            85:     D(printf("%s %x=%x\n", __func__, addr, rval));
        !            86:     return rval;
1.1       root       87: }
                     88: 
                     89: static void
                     90: pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
                     91: {
1.1.1.2 ! root       92:     struct etrax_pic *fs = opaque;
        !            93:     D(printf("%s addr=%x val=%x\n", __func__, addr, value));
        !            94: 
        !            95:     if (addr == R_RW_MASK) {
        !            96:         fs->regs[R_RW_MASK] = value;
        !            97:         pic_update(fs);
        !            98:     }
1.1       root       99: }
                    100: 
                    101: static CPUReadMemoryFunc *pic_read[] = {
1.1.1.2 ! root      102:     NULL, NULL,
        !           103:     &pic_readl,
1.1       root      104: };
                    105: 
                    106: static CPUWriteMemoryFunc *pic_write[] = {
1.1.1.2 ! root      107:     NULL, NULL,
        !           108:     &pic_writel,
1.1       root      109: };
                    110: 
1.1.1.2 ! root      111: static void nmi_handler(void *opaque, int irq, int level)
        !           112: {   
        !           113:     struct etrax_pic *fs = (void *)opaque;
        !           114:     uint32_t mask;
        !           115: 
        !           116:     mask = 1 << irq;
        !           117:     if (level)
        !           118:         fs->regs[R_R_NMI] |= mask;
        !           119:     else
        !           120:         fs->regs[R_R_NMI] &= ~mask;
1.1       root      121: 
1.1.1.2 ! root      122:     qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]);
1.1       root      123: }
                    124: 
                    125: static void irq_handler(void *opaque, int irq, int level)
1.1.1.2 ! root      126: {   
        !           127:     struct etrax_pic *fs = (void *)opaque;
1.1       root      128: 
1.1.1.2 ! root      129:     if (irq >= 30)
        !           130:         return nmi_handler(opaque, irq, level);
1.1       root      131: 
1.1.1.2 ! root      132:     irq -= 1;
        !           133:     fs->regs[R_R_VECT] &= ~(1 << irq);
        !           134:     fs->regs[R_R_VECT] |= (!!level << irq);
        !           135:     pic_update(fs);
        !           136: }
        !           137: 
        !           138: static void etraxfs_pic_init(SysBusDevice *dev)
        !           139: {
        !           140:     struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev);
        !           141:     int intr_vect_regs;
        !           142: 
        !           143:     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
        !           144:     sysbus_init_irq(dev, &s->parent_irq);
        !           145:     sysbus_init_irq(dev, &s->parent_nmi);
        !           146: 
        !           147:     intr_vect_regs = cpu_register_io_memory(pic_read, pic_write, s);
        !           148:     sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs);
        !           149: }
        !           150: 
        !           151: static SysBusDeviceInfo etraxfs_pic_info = {
        !           152:     .init = etraxfs_pic_init,
        !           153:     .qdev.name  = "etraxfs,pic",
        !           154:     .qdev.size  = sizeof(struct etrax_pic),
        !           155:     .qdev.props = (Property[]) {
        !           156:         {
        !           157:             .name   = "interrupt_vector",
        !           158:             .info   = &qdev_prop_ptr,
        !           159:             .offset = offsetof(struct etrax_pic, interrupt_vector),
        !           160:         },
        !           161:         {/* end of list */}
        !           162:     }
        !           163: };
1.1       root      164: 
1.1.1.2 ! root      165: static void etraxfs_pic_register(void)
1.1       root      166: {
1.1.1.2 ! root      167:     sysbus_register_withprop(&etraxfs_pic_info);
1.1       root      168: }
1.1.1.2 ! root      169: 
        !           170: device_init(etraxfs_pic_register)

unix.superglobalmegacorp.com

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