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

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;
1.1.1.5   root       42:     MemoryRegion mmio;
1.1.1.3   root       43:     void *interrupt_vector;
1.1.1.2   root       44:     qemu_irq parent_irq;
                     45:     qemu_irq parent_nmi;
                     46:     uint32_t regs[R_MAX];
1.1       root       47: };
                     48: 
1.1.1.2   root       49: static void pic_update(struct etrax_pic *fs)
                     50: {   
                     51:     uint32_t vector = 0;
                     52:     int i;
                     53: 
                     54:     fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
                     55: 
1.1.1.6 ! root       56:     /* The ETRAX interrupt controller signals interrupts to the core
1.1.1.2   root       57:        through an interrupt request wire and an irq vector bus. If 
                     58:        multiple interrupts are simultaneously active it chooses vector 
                     59:        0x30 and lets the sw choose the priorities.  */
                     60:     if (fs->regs[R_R_MASKED_VECT]) {
                     61:         uint32_t mv = fs->regs[R_R_MASKED_VECT];
                     62:         for (i = 0; i < 31; i++) {
                     63:             if (mv & 1) {
                     64:                 vector = 0x31 + i;
                     65:                 /* Check for multiple interrupts.  */
                     66:                 if (mv > 1)
                     67:                     vector = 0x30;
                     68:                 break;
                     69:             }
                     70:             mv >>= 1;
                     71:         }
                     72:     }
                     73: 
                     74:     if (fs->interrupt_vector) {
1.1.1.3   root       75:         /* hack alert: ptr property */
                     76:         *(uint32_t*)(fs->interrupt_vector) = vector;
1.1.1.2   root       77:     }
                     78:     qemu_set_irq(fs->parent_irq, !!vector);
1.1       root       79: }
                     80: 
1.1.1.5   root       81: static uint64_t
                     82: pic_read(void *opaque, target_phys_addr_t addr, unsigned int size)
1.1       root       83: {
1.1.1.2   root       84:     struct etrax_pic *fs = opaque;
                     85:     uint32_t rval;
1.1       root       86: 
1.1.1.2   root       87:     rval = fs->regs[addr >> 2];
                     88:     D(printf("%s %x=%x\n", __func__, addr, rval));
                     89:     return rval;
1.1       root       90: }
                     91: 
1.1.1.5   root       92: static void pic_write(void *opaque, target_phys_addr_t addr,
                     93:                       uint64_t value, unsigned int size)
1.1       root       94: {
1.1.1.2   root       95:     struct etrax_pic *fs = opaque;
                     96:     D(printf("%s addr=%x val=%x\n", __func__, addr, value));
                     97: 
                     98:     if (addr == R_RW_MASK) {
                     99:         fs->regs[R_RW_MASK] = value;
                    100:         pic_update(fs);
                    101:     }
1.1       root      102: }
                    103: 
1.1.1.5   root      104: static const MemoryRegionOps pic_ops = {
                    105:     .read = pic_read,
                    106:     .write = pic_write,
                    107:     .endianness = DEVICE_NATIVE_ENDIAN,
                    108:     .valid = {
                    109:         .min_access_size = 4,
                    110:         .max_access_size = 4
                    111:     }
1.1       root      112: };
                    113: 
1.1.1.2   root      114: static void nmi_handler(void *opaque, int irq, int level)
                    115: {   
                    116:     struct etrax_pic *fs = (void *)opaque;
                    117:     uint32_t mask;
                    118: 
                    119:     mask = 1 << irq;
                    120:     if (level)
                    121:         fs->regs[R_R_NMI] |= mask;
                    122:     else
                    123:         fs->regs[R_R_NMI] &= ~mask;
1.1       root      124: 
1.1.1.2   root      125:     qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]);
1.1       root      126: }
                    127: 
                    128: static void irq_handler(void *opaque, int irq, int level)
1.1.1.2   root      129: {   
                    130:     struct etrax_pic *fs = (void *)opaque;
1.1       root      131: 
1.1.1.2   root      132:     if (irq >= 30)
                    133:         return nmi_handler(opaque, irq, level);
1.1       root      134: 
1.1.1.2   root      135:     irq -= 1;
                    136:     fs->regs[R_R_VECT] &= ~(1 << irq);
                    137:     fs->regs[R_R_VECT] |= (!!level << irq);
                    138:     pic_update(fs);
                    139: }
                    140: 
1.1.1.3   root      141: static int etraxfs_pic_init(SysBusDevice *dev)
1.1.1.2   root      142: {
                    143:     struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev);
                    144: 
                    145:     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
                    146:     sysbus_init_irq(dev, &s->parent_irq);
                    147:     sysbus_init_irq(dev, &s->parent_nmi);
                    148: 
1.1.1.5   root      149:     memory_region_init_io(&s->mmio, &pic_ops, s, "etraxfs-pic", R_MAX * 4);
1.1.1.6 ! root      150:     sysbus_init_mmio(dev, &s->mmio);
1.1.1.3   root      151:     return 0;
1.1.1.2   root      152: }
                    153: 
1.1.1.6 ! root      154: static Property etraxfs_pic_properties[] = {
        !           155:     DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
        !           156:     DEFINE_PROP_END_OF_LIST(),
        !           157: };
        !           158: 
        !           159: static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
        !           160: {
        !           161:     DeviceClass *dc = DEVICE_CLASS(klass);
        !           162:     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
        !           163: 
        !           164:     k->init = etraxfs_pic_init;
        !           165:     dc->props = etraxfs_pic_properties;
        !           166: }
        !           167: 
        !           168: static TypeInfo etraxfs_pic_info = {
        !           169:     .name          = "etraxfs,pic",
        !           170:     .parent        = TYPE_SYS_BUS_DEVICE,
        !           171:     .instance_size = sizeof(struct etrax_pic),
        !           172:     .class_init    = etraxfs_pic_class_init,
1.1.1.2   root      173: };
1.1       root      174: 
1.1.1.6 ! root      175: static void etraxfs_pic_register_types(void)
1.1       root      176: {
1.1.1.6 ! root      177:     type_register_static(&etraxfs_pic_info);
1.1       root      178: }
1.1.1.2   root      179: 
1.1.1.6 ! root      180: type_init(etraxfs_pic_register_types)

unix.superglobalmegacorp.com

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