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

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.3   root       42:     void *interrupt_vector;
1.1.1.2   root       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) {
1.1.1.3   root       74:         /* hack alert: ptr property */
                     75:         *(uint32_t*)(fs->interrupt_vector) = vector;
1.1.1.2   root       76:     }
                     77:     qemu_set_irq(fs->parent_irq, !!vector);
1.1       root       78: }
                     79: 
                     80: static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
                     81: {
1.1.1.2   root       82:     struct etrax_pic *fs = opaque;
                     83:     uint32_t rval;
1.1       root       84: 
1.1.1.2   root       85:     rval = fs->regs[addr >> 2];
                     86:     D(printf("%s %x=%x\n", __func__, addr, rval));
                     87:     return rval;
1.1       root       88: }
                     89: 
                     90: static void
                     91: pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
                     92: {
1.1.1.2   root       93:     struct etrax_pic *fs = opaque;
                     94:     D(printf("%s addr=%x val=%x\n", __func__, addr, value));
                     95: 
                     96:     if (addr == R_RW_MASK) {
                     97:         fs->regs[R_RW_MASK] = value;
                     98:         pic_update(fs);
                     99:     }
1.1       root      100: }
                    101: 
1.1.1.3   root      102: static CPUReadMemoryFunc * const pic_read[] = {
1.1.1.2   root      103:     NULL, NULL,
                    104:     &pic_readl,
1.1       root      105: };
                    106: 
1.1.1.3   root      107: static CPUWriteMemoryFunc * const pic_write[] = {
1.1.1.2   root      108:     NULL, NULL,
                    109:     &pic_writel,
1.1       root      110: };
                    111: 
1.1.1.2   root      112: static void nmi_handler(void *opaque, int irq, int level)
                    113: {   
                    114:     struct etrax_pic *fs = (void *)opaque;
                    115:     uint32_t mask;
                    116: 
                    117:     mask = 1 << irq;
                    118:     if (level)
                    119:         fs->regs[R_R_NMI] |= mask;
                    120:     else
                    121:         fs->regs[R_R_NMI] &= ~mask;
1.1       root      122: 
1.1.1.2   root      123:     qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]);
1.1       root      124: }
                    125: 
                    126: static void irq_handler(void *opaque, int irq, int level)
1.1.1.2   root      127: {   
                    128:     struct etrax_pic *fs = (void *)opaque;
1.1       root      129: 
1.1.1.2   root      130:     if (irq >= 30)
                    131:         return nmi_handler(opaque, irq, level);
1.1       root      132: 
1.1.1.2   root      133:     irq -= 1;
                    134:     fs->regs[R_R_VECT] &= ~(1 << irq);
                    135:     fs->regs[R_R_VECT] |= (!!level << irq);
                    136:     pic_update(fs);
                    137: }
                    138: 
1.1.1.3   root      139: static int etraxfs_pic_init(SysBusDevice *dev)
1.1.1.2   root      140: {
                    141:     struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev);
                    142:     int intr_vect_regs;
                    143: 
                    144:     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
                    145:     sysbus_init_irq(dev, &s->parent_irq);
                    146:     sysbus_init_irq(dev, &s->parent_nmi);
                    147: 
1.1.1.4 ! root      148:     intr_vect_regs = cpu_register_io_memory(pic_read, pic_write, s,
        !           149:                                             DEVICE_NATIVE_ENDIAN);
1.1.1.2   root      150:     sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs);
1.1.1.3   root      151:     return 0;
1.1.1.2   root      152: }
                    153: 
                    154: static SysBusDeviceInfo etraxfs_pic_info = {
                    155:     .init = etraxfs_pic_init,
                    156:     .qdev.name  = "etraxfs,pic",
                    157:     .qdev.size  = sizeof(struct etrax_pic),
                    158:     .qdev.props = (Property[]) {
1.1.1.3   root      159:         DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
                    160:         DEFINE_PROP_END_OF_LIST(),
1.1.1.2   root      161:     }
                    162: };
1.1       root      163: 
1.1.1.2   root      164: static void etraxfs_pic_register(void)
1.1       root      165: {
1.1.1.2   root      166:     sysbus_register_withprop(&etraxfs_pic_info);
1.1       root      167: }
1.1.1.2   root      168: 
                    169: 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.