qemu

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

irq.c (3420B)


      1 /*
      2  * QEMU IRQ/GPIO common code.
      3  *
      4  * Copyright (c) 2007 CodeSourcery.
      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 #include "qemu/osdep.h"
     25 #include "qemu/main-loop.h"
     26 #include "hw/irq.h"
     27 #include "qom/object.h"
     28 
     29 DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ,
     30                          TYPE_IRQ)
     31 
     32 struct IRQState {
     33     Object parent_obj;
     34 
     35     qemu_irq_handler handler;
     36     void *opaque;
     37     int n;
     38 };
     39 
     40 void qemu_set_irq(qemu_irq irq, int level)
     41 {
     42     if (!irq)
     43         return;
     44 
     45     irq->handler(irq->opaque, irq->n, level);
     46 }
     47 
     48 qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
     49                            void *opaque, int n)
     50 {
     51     qemu_irq *s;
     52     int i;
     53 
     54     if (!old) {
     55         n_old = 0;
     56     }
     57     s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n);
     58     for (i = n_old; i < n + n_old; i++) {
     59         s[i] = qemu_allocate_irq(handler, opaque, i);
     60     }
     61     return s;
     62 }
     63 
     64 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
     65 {
     66     return qemu_extend_irqs(NULL, 0, handler, opaque, n);
     67 }
     68 
     69 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
     70 {
     71     struct IRQState *irq;
     72 
     73     irq = IRQ(object_new(TYPE_IRQ));
     74     irq->handler = handler;
     75     irq->opaque = opaque;
     76     irq->n = n;
     77 
     78     return irq;
     79 }
     80 
     81 void qemu_free_irqs(qemu_irq *s, int n)
     82 {
     83     int i;
     84     for (i = 0; i < n; i++) {
     85         qemu_free_irq(s[i]);
     86     }
     87     g_free(s);
     88 }
     89 
     90 void qemu_free_irq(qemu_irq irq)
     91 {
     92     object_unref(OBJECT(irq));
     93 }
     94 
     95 static void qemu_notirq(void *opaque, int line, int level)
     96 {
     97     struct IRQState *irq = opaque;
     98 
     99     irq->handler(irq->opaque, irq->n, !level);
    100 }
    101 
    102 qemu_irq qemu_irq_invert(qemu_irq irq)
    103 {
    104     /* The default state for IRQs is low, so raise the output now.  */
    105     qemu_irq_raise(irq);
    106     return qemu_allocate_irq(qemu_notirq, irq, 0);
    107 }
    108 
    109 void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
    110 {
    111     int i;
    112     qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
    113     for (i = 0; i < n; i++) {
    114         *old_irqs[i] = *gpio_in[i];
    115         gpio_in[i]->handler = handler;
    116         gpio_in[i]->opaque = &old_irqs[i];
    117     }
    118 }
    119 
    120 static const TypeInfo irq_type_info = {
    121    .name = TYPE_IRQ,
    122    .parent = TYPE_OBJECT,
    123    .instance_size = sizeof(struct IRQState),
    124 };
    125 
    126 static void irq_register_types(void)
    127 {
    128     type_register_static(&irq_type_info);
    129 }
    130 
    131 type_init(irq_register_types)