qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 5/6] Add the aehd-i8259 device type.


From: Haitao Shan
Subject: [PATCH 5/6] Add the aehd-i8259 device type.
Date: Thu, 2 Mar 2023 18:26:16 -0800

The aehd-i8259 device type represents the AEHD in kernel PICs.
The irqchips should be always in kernel when AEHD is used.

Signed-off-by: Haitao Shan <hshan@google.com>
---
 hw/i386/aehd/i8259.c     | 165 +++++++++++++++++++++++++++++++++++++++
 hw/i386/aehd/meson.build |   1 +
 hw/i386/pc.c             |   2 +
 include/hw/intc/i8259.h  |   1 +
 4 files changed, 169 insertions(+)
 create mode 100644 hw/i386/aehd/i8259.c

diff --git a/hw/i386/aehd/i8259.c b/hw/i386/aehd/i8259.c
new file mode 100644
index 0000000000..9a18e824dc
--- /dev/null
+++ b/hw/i386/aehd/i8259.c
@@ -0,0 +1,165 @@
+/*
+ * AEHD in-kernel PIC (i8259) support
+ *
+ * Copyright (c) 2011 Siemens AG
+ *
+ * Authors:
+ *  Jan Kiszka          <jan.kiszka@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "hw/isa/i8259_internal.h"
+#include "hw/i386/apic_internal.h"
+#include "sysemu/aehd.h"
+#include "sysemu/aehd-interface.h"
+
+#define TYPE_AEHD_I8259 "aehd-i8259"
+#define AEHD_PIC_CLASS(class) \
+    OBJECT_CLASS_CHECK(AEHDPICClass, (class), TYPE_AEHD_I8259)
+#define AEHD_PIC_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(AEHDPICClass, (obj), TYPE_AEHD_I8259)
+
+/**
+ * AEHDPICClass:
+ * @parent_realize: The parent's realizefn.
+ */
+typedef struct AEHDPICClass {
+    PICCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} AEHDPICClass;
+
+static void aehd_pic_get(PICCommonState *s)
+{
+    struct aehd_irqchip chip;
+    struct aehd_pic_state *aepic;
+    int ret;
+
+    chip.chip_id = s->master ? AEHD_IRQCHIP_PIC_MASTER : 
AEHD_IRQCHIP_PIC_SLAVE;
+    ret = aehd_vm_ioctl(aehd_state, AEHD_GET_IRQCHIP, &chip, sizeof(chip),
+                        &chip, sizeof(chip));
+    if (ret < 0) {
+        fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+        abort();
+    }
+
+    aepic = &chip.chip.pic;
+
+    s->last_irr = aepic->last_irr;
+    s->irr = aepic->irr;
+    s->imr = aepic->imr;
+    s->isr = aepic->isr;
+    s->priority_add = aepic->priority_add;
+    s->irq_base = aepic->irq_base;
+    s->read_reg_select = aepic->read_reg_select;
+    s->poll = aepic->poll;
+    s->special_mask = aepic->special_mask;
+    s->init_state = aepic->init_state;
+    s->auto_eoi = aepic->auto_eoi;
+    s->rotate_on_auto_eoi = aepic->rotate_on_auto_eoi;
+    s->special_fully_nested_mode = aepic->special_fully_nested_mode;
+    s->init4 = aepic->init4;
+    s->elcr = aepic->elcr;
+    s->elcr_mask = aepic->elcr_mask;
+}
+
+static void aehd_pic_put(PICCommonState *s)
+{
+    struct aehd_irqchip chip;
+    struct aehd_pic_state *aepic;
+    int ret;
+
+    chip.chip_id = s->master ? AEHD_IRQCHIP_PIC_MASTER : 
AEHD_IRQCHIP_PIC_SLAVE;
+
+    aepic = &chip.chip.pic;
+
+    aepic->last_irr = s->last_irr;
+    aepic->irr = s->irr;
+    aepic->imr = s->imr;
+    aepic->isr = s->isr;
+    aepic->priority_add = s->priority_add;
+    aepic->irq_base = s->irq_base;
+    aepic->read_reg_select = s->read_reg_select;
+    aepic->poll = s->poll;
+    aepic->special_mask = s->special_mask;
+    aepic->init_state = s->init_state;
+    aepic->auto_eoi = s->auto_eoi;
+    aepic->rotate_on_auto_eoi = s->rotate_on_auto_eoi;
+    aepic->special_fully_nested_mode = s->special_fully_nested_mode;
+    aepic->init4 = s->init4;
+    aepic->elcr = s->elcr;
+    aepic->elcr_mask = s->elcr_mask;
+
+    ret = aehd_vm_ioctl(aehd_state, AEHD_SET_IRQCHIP,
+                        &chip, sizeof(chip), NULL, 0);
+    if (ret < 0) {
+        fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+        abort();
+    }
+}
+
+static void aehd_pic_reset(DeviceState *dev)
+{
+    PICCommonState *s = PIC_COMMON(dev);
+
+    s->elcr = 0;
+    pic_reset_common(s);
+
+    aehd_pic_put(s);
+}
+
+static void aehd_pic_set_irq(void *opaque, int irq, int level)
+{
+    pic_stat_update_irq(irq, level);
+    aehd_set_irq(aehd_state, irq, level);
+}
+
+static void aehd_pic_realize(DeviceState *dev, Error **errp)
+{
+    PICCommonState *s = PIC_COMMON(dev);
+    AEHDPICClass *kpc = AEHD_PIC_GET_CLASS(dev);
+
+    memory_region_init_io(&s->base_io, OBJECT(dev), NULL, NULL, "aehd-pic", 2);
+    memory_region_init_io(&s->elcr_io, OBJECT(dev), NULL, NULL, "aehd-elcr", 
1);
+
+
+    kpc->parent_realize(dev, errp);
+}
+
+qemu_irq *aehd_i8259_init(ISABus *bus)
+{
+    i8259_init_chip(TYPE_AEHD_I8259, bus, true);
+    i8259_init_chip(TYPE_AEHD_I8259, bus, false);
+
+    return qemu_allocate_irqs(aehd_pic_set_irq, NULL, ISA_NUM_IRQS);
+}
+
+static void aehd_i8259_class_init(ObjectClass *klass, void *data)
+{
+    AEHDPICClass *kpc = AEHD_PIC_CLASS(klass);
+    PICCommonClass *k = PIC_COMMON_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset     = aehd_pic_reset;
+    kpc->parent_realize = dc->realize;
+    dc->realize   = aehd_pic_realize;
+    k->pre_save   = aehd_pic_get;
+    k->post_load  = aehd_pic_put;
+}
+
+static const TypeInfo aehd_i8259_info = {
+    .name = TYPE_AEHD_I8259,
+    .parent = TYPE_PIC_COMMON,
+    .instance_size = sizeof(PICCommonState),
+    .class_init = aehd_i8259_class_init,
+    .class_size = sizeof(AEHDPICClass),
+};
+
+static void aehd_pic_register_types(void)
+{
+    type_register_static(&aehd_i8259_info);
+}
+
+type_init(aehd_pic_register_types)
diff --git a/hw/i386/aehd/meson.build b/hw/i386/aehd/meson.build
index 259c9f66f7..90c9a3e2b6 100644
--- a/hw/i386/aehd/meson.build
+++ b/hw/i386/aehd/meson.build
@@ -1,5 +1,6 @@
 i386_aehd_ss = ss.source_set()
 i386_aehd_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c'))
+i386_aehd_ss.add(when: 'CONFIG_I8259', if_true: files('i8259.c'))
 i386_aehd_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
 
 i386_ss.add_all(when: 'CONFIG_AEHD', if_true: i386_aehd_ss)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 59513a5c38..3b45f75fbd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1356,6 +1356,8 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq 
*i8259_irqs)
 
     if (kvm_pic_in_kernel()) {
         i8259 = kvm_i8259_init(isa_bus);
+    } else if (aehd_enabled()) {
+        i8259 = aehd_i8259_init(isa_bus);
     } else if (xen_enabled()) {
         i8259 = xen_interrupt_controller_init();
     } else {
diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h
index c412575775..5ce85ed590 100644
--- a/include/hw/intc/i8259.h
+++ b/include/hw/intc/i8259.h
@@ -14,6 +14,7 @@ extern PICCommonState *isa_pic;
  */
 qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq_in);
 qemu_irq *kvm_i8259_init(ISABus *bus);
+qemu_irq *aehd_i8259_init(ISABus *bus);
 int pic_get_output(PICCommonState *s);
 int pic_read_irq(PICCommonState *s);
 
-- 
2.40.0.rc0.216.gc4246ad0f0-goog




reply via email to

[Prev in Thread] Current Thread [Next in Thread]