qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

heathrow_pic.c (5761B)


      1 /*
      2  * Heathrow PIC support (OldWorld PowerMac)
      3  *
      4  * Copyright (c) 2005-2007 Fabrice Bellard
      5  * Copyright (c) 2007 Jocelyn Mayer
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 
     26 #include "qemu/osdep.h"
     27 #include "migration/vmstate.h"
     28 #include "qemu/module.h"
     29 #include "hw/intc/heathrow_pic.h"
     30 #include "hw/irq.h"
     31 #include "trace.h"
     32 
     33 static inline int heathrow_check_irq(HeathrowPICState *pic)
     34 {
     35     return (pic->events | (pic->levels & pic->level_triggered)) & pic->mask;
     36 }
     37 
     38 /* update the CPU irq state */
     39 static void heathrow_update_irq(HeathrowState *s)
     40 {
     41     if (heathrow_check_irq(&s->pics[0]) ||
     42             heathrow_check_irq(&s->pics[1])) {
     43         qemu_irq_raise(s->irqs[0]);
     44     } else {
     45         qemu_irq_lower(s->irqs[0]);
     46     }
     47 }
     48 
     49 static void heathrow_write(void *opaque, hwaddr addr,
     50                            uint64_t value, unsigned size)
     51 {
     52     HeathrowState *s = opaque;
     53     HeathrowPICState *pic;
     54     unsigned int n;
     55 
     56     n = ((addr & 0xfff) - 0x10) >> 4;
     57     trace_heathrow_write(addr, n, value);
     58     if (n >= 2)
     59         return;
     60     pic = &s->pics[n];
     61     switch(addr & 0xf) {
     62     case 0x04:
     63         pic->mask = value;
     64         heathrow_update_irq(s);
     65         break;
     66     case 0x08:
     67         /* do not reset level triggered IRQs */
     68         value &= ~pic->level_triggered;
     69         pic->events &= ~value;
     70         heathrow_update_irq(s);
     71         break;
     72     default:
     73         break;
     74     }
     75 }
     76 
     77 static uint64_t heathrow_read(void *opaque, hwaddr addr,
     78                               unsigned size)
     79 {
     80     HeathrowState *s = opaque;
     81     HeathrowPICState *pic;
     82     unsigned int n;
     83     uint32_t value;
     84 
     85     n = ((addr & 0xfff) - 0x10) >> 4;
     86     if (n >= 2) {
     87         value = 0;
     88     } else {
     89         pic = &s->pics[n];
     90         switch(addr & 0xf) {
     91         case 0x0:
     92             value = pic->events;
     93             break;
     94         case 0x4:
     95             value = pic->mask;
     96             break;
     97         case 0xc:
     98             value = pic->levels;
     99             break;
    100         default:
    101             value = 0;
    102             break;
    103         }
    104     }
    105     trace_heathrow_read(addr, n, value);
    106     return value;
    107 }
    108 
    109 static const MemoryRegionOps heathrow_ops = {
    110     .read = heathrow_read,
    111     .write = heathrow_write,
    112     .endianness = DEVICE_LITTLE_ENDIAN,
    113 };
    114 
    115 static void heathrow_set_irq(void *opaque, int num, int level)
    116 {
    117     HeathrowState *s = opaque;
    118     HeathrowPICState *pic;
    119     unsigned int irq_bit;
    120     int last_level;
    121 
    122     pic = &s->pics[1 - (num >> 5)];
    123     irq_bit = 1 << (num & 0x1f);
    124     last_level = (pic->levels & irq_bit) ? 1 : 0;
    125 
    126     if (level) {
    127         pic->events |= irq_bit & ~pic->level_triggered;
    128         pic->levels |= irq_bit;
    129     } else {
    130         pic->levels &= ~irq_bit;
    131     }
    132 
    133     if (last_level != level) {
    134         trace_heathrow_set_irq(num, level);
    135     }
    136 
    137     heathrow_update_irq(s);
    138 }
    139 
    140 static const VMStateDescription vmstate_heathrow_pic_one = {
    141     .name = "heathrow_pic_one",
    142     .version_id = 0,
    143     .minimum_version_id = 0,
    144     .fields = (VMStateField[]) {
    145         VMSTATE_UINT32(events, HeathrowPICState),
    146         VMSTATE_UINT32(mask, HeathrowPICState),
    147         VMSTATE_UINT32(levels, HeathrowPICState),
    148         VMSTATE_UINT32(level_triggered, HeathrowPICState),
    149         VMSTATE_END_OF_LIST()
    150     }
    151 };
    152 
    153 static const VMStateDescription vmstate_heathrow = {
    154     .name = "heathrow_pic",
    155     .version_id = 1,
    156     .minimum_version_id = 1,
    157     .fields = (VMStateField[]) {
    158         VMSTATE_STRUCT_ARRAY(pics, HeathrowState, 2, 1,
    159                              vmstate_heathrow_pic_one, HeathrowPICState),
    160         VMSTATE_END_OF_LIST()
    161     }
    162 };
    163 
    164 static void heathrow_reset(DeviceState *d)
    165 {
    166     HeathrowState *s = HEATHROW(d);
    167 
    168     s->pics[0].level_triggered = 0;
    169     s->pics[1].level_triggered = 0x1ff00000;
    170 }
    171 
    172 static void heathrow_init(Object *obj)
    173 {
    174     HeathrowState *s = HEATHROW(obj);
    175     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    176 
    177     /* only 1 CPU */
    178     qdev_init_gpio_out(DEVICE(obj), s->irqs, 1);
    179 
    180     qdev_init_gpio_in(DEVICE(obj), heathrow_set_irq, HEATHROW_NUM_IRQS);
    181 
    182     memory_region_init_io(&s->mem, OBJECT(s), &heathrow_ops, s,
    183                           "heathrow-pic", 0x1000);
    184     sysbus_init_mmio(sbd, &s->mem);
    185 }
    186 
    187 static void heathrow_class_init(ObjectClass *oc, void *data)
    188 {
    189     DeviceClass *dc = DEVICE_CLASS(oc);
    190 
    191     dc->reset = heathrow_reset;
    192     dc->vmsd = &vmstate_heathrow;
    193     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    194 }
    195 
    196 static const TypeInfo heathrow_type_info = {
    197     .name = TYPE_HEATHROW,
    198     .parent = TYPE_SYS_BUS_DEVICE,
    199     .instance_size = sizeof(HeathrowState),
    200     .instance_init = heathrow_init,
    201     .class_init = heathrow_class_init,
    202 };
    203 
    204 static void heathrow_register_types(void)
    205 {
    206     type_register_static(&heathrow_type_info);
    207 }
    208 
    209 type_init(heathrow_register_types)