qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 58/61] ioapic: make the number of pins configurable.


From: Isaku Yamahata
Subject: [Qemu-devel] [PATCH 58/61] ioapic: make the number of pins configurable.
Date: Wed, 30 Sep 2009 19:18:34 +0900

make the number of pins configurable.

Signed-off-by: Isaku Yamahata <address@hidden>
---
 hw/hw.h     |   20 +++++++++++++++++
 hw/ioapic.c |   66 ++++++++++++++++++++++++++++++++++++++++++++--------------
 hw/pc.h     |    3 +-
 3 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 19e9199..6f78285 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -365,6 +365,17 @@ extern const VMStateInfo vmstate_info_buffer;
         + type_check_array(_type,typeof_field(_state, _field),_num)  \
 }
 
+#define VMSTATE_ARRAY_POINTER(_field, _state, _num, _version, _info, _type) {\
+    .name       = (stringify(_field)),                               \
+    .version_id = (_version),                                        \
+    .num        = (_num),                                            \
+    .info       = &(_info),                                          \
+    .size       = sizeof(_type),                                     \
+    .flags      = VMS_ARRAY|VMS_POINTER,                             \
+    .offset     = offsetof(_state, _field)                           \
+        + type_check_pointer(_type,typeof_field(_state, _field))     \
+}
+
 #define VMSTATE_VARRAY(_field, _state, _field_num, _version, _info, _type) {\
     .name       = (stringify(_field)),                               \
     .version_id = (_version),                                        \
@@ -532,6 +543,15 @@ extern const VMStateDescription vmstate_pcie_device;
 #define VMSTATE_UINT64_ARRAY(_f, _s, _n)                              \
     VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
 
+#define VMSTATE_UINT64_ARRAY_POINTER(_f, _s, _n)                      \
+    VMSTATE_ARRAY_POINTER(_f, _s, _n, 0, vmstate_info_uint64, uint64_t)
+
+#define VMSTATE_UINT64_VARRAY_V(_f, _s, _f_n, _v)                     \
+    VMSTATE_VARRAY(_f, _s, _f_n, _v, vmstate_info_uint64, uint64_t)
+
+#define VMSTATE_UINT64_VARRAY(_f, _s, _f_n)                           \
+    VMSTATE_UINT64_VARRAY_V(_f, _s, _f_n, 0)
+
 #define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v)                         \
     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t)
 
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 882ca9d..adaef41 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -32,7 +32,7 @@
 # define IOAPIC_DPRINTF(format, ...)    do { } while (0)
 #endif
 
-#define IOAPIC_NUM_PINS                        0x18
+#define IOAPIC_NUM_PINS_DEFAULT                0x18
 #define IOAPIC_LVT_MASKED              (1<<16)
 
 #define IOAPIC_TRIGGER_EDGE            0
@@ -48,11 +48,12 @@
 #define IOAPIC_DM_EXTINT               0x7
 
 struct IOAPICState {
+    int32_t num_pins;   /* MRE: maximum redirection entries */
     uint8_t id;
     uint8_t ioregsel;
 
     uint32_t irr;
-    uint64_t ioredtbl[IOAPIC_NUM_PINS];
+    uint64_t *ioredtbl;
     ioapic_update_fn update_fn;
     void *opaque;
 };
@@ -75,7 +76,7 @@ static void ioapic_service(IOAPICState *s)
     uint8_t dest_mode;
     uint8_t polarity;
 
-    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+    for (i = 0; i < s->num_pins; i++) {
         mask = 1 << i;
         if (s->irr & mask) {
             entry = s->ioredtbl[i];
@@ -110,7 +111,7 @@ static void ioapic_set_irq(void *opaque, int vector, int 
level)
     if (vector == 0)
         vector = 2;
 
-    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
+    if (vector >= 0 && vector < s->num_pins) {
         uint32_t mask = 1 << vector;
         uint64_t entry = s->ioredtbl[vector];
 
@@ -147,14 +148,14 @@ static uint32_t ioapic_mem_readl(void *opaque, 
target_phys_addr_t addr)
                 val = s->id << 24;
                 break;
             case 0x01:
-                val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
+                val = 0x11 | ((s->num_pins - 1) << 16); /* version 0x11 */
                 break;
             case 0x02:
                 val = 0;
                 break;
             default:
                 index = (s->ioregsel - 0x10) >> 1;
-                if (index >= 0 && index < IOAPIC_NUM_PINS) {
+                if (index >= 0 && index < s->num_pins) {
                     if (s->ioregsel & 1)
                         val = s->ioredtbl[index] >> 32;
                     else
@@ -186,7 +187,7 @@ static void ioapic_mem_writel(void *opaque, 
target_phys_addr_t addr, uint32_t va
                 return;
             default:
                 index = (s->ioregsel - 0x10) >> 1;
-                if (index >= 0 && index < IOAPIC_NUM_PINS) {
+                if (index >= 0 && index < s->num_pins) {
                     if (s->ioregsel & 1) {
                         s->ioredtbl[index] &= 0xffffffff;
                         s->ioredtbl[index] |= (uint64_t)val << 32;
@@ -209,7 +210,22 @@ static const VMStateDescription vmstate_ioapic = {
     .fields      = (VMStateField []) {
         VMSTATE_UINT8(id, IOAPICState),
         VMSTATE_UINT8(ioregsel, IOAPICState),
-        VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS),
+        VMSTATE_UINT64_ARRAY_POINTER(ioredtbl, IOAPICState,
+                                     IOAPIC_NUM_PINS_DEFAULT),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_ioapic_with_mre = {
+    .name = "ioapic",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_INT32(num_pins, IOAPICState),
+        VMSTATE_UINT8(id, IOAPICState),
+        VMSTATE_UINT8(ioregsel, IOAPICState),
+        VMSTATE_UINT64_VARRAY(ioredtbl, IOAPICState, num_pins),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -221,8 +237,10 @@ static void ioapic_reset(void *opaque)
 
     ioapic_callback(s, 1);
 
-    memset(s, 0, sizeof(*s));
-    for(i = 0; i < IOAPIC_NUM_PINS; i++)
+    s->id = 0;
+    s->ioregsel = 0;
+    s->irr = 0;
+    for(i = 0; i < s->num_pins; i++)
         s->ioredtbl[i] = 1 << 16; /* mask LVT */
 }
 
@@ -238,13 +256,18 @@ static CPUWriteMemoryFunc * const ioapic_mem_write[3] = {
     ioapic_mem_writel,
 };
 
-qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque)
+static void ioapic_init_with_arg(uint8_t num_pins,
+                                 ioapic_update_fn update_fn, void *opaque,
+                                 IOAPICState **sp, qemu_irq **irq)
 {
     IOAPICState *s;
-    qemu_irq *irq;
     int io_memory;
 
-    s = qemu_mallocz(sizeof(IOAPICState));
+    s = qemu_mallocz(sizeof(*s));
+    *sp = s;
+
+    s->ioredtbl = qemu_mallocz(sizeof(s->ioredtbl[0]) * num_pins);
+    s->num_pins = num_pins;
     s->update_fn = update_fn;
     s->opaque = opaque;
     ioapic_reset(s);
@@ -253,14 +276,25 @@ qemu_irq *ioapic_init_with_arg(ioapic_update_fn 
update_fn, void *opaque)
                                        ioapic_mem_write, s);
     cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
 
-    vmstate_register(0, &vmstate_ioapic, s);
     qemu_register_reset(ioapic_reset, s);
-    irq = qemu_allocate_irqs(ioapic_set_irq, s, IOAPIC_NUM_PINS);
+    *irq = qemu_allocate_irqs(ioapic_set_irq, s, num_pins);
+}
 
+qemu_irq *ioapic_init_with_mre(uint8_t num_pins,
+                               ioapic_update_fn update_fn, void *opaque)
+{
+    IOAPICState *s;
+    qemu_irq *irq;
+    ioapic_init_with_arg(num_pins, update_fn, opaque, &s, &irq);
+    vmstate_register(0, &vmstate_ioapic_with_mre, s);
     return irq;
 }
 
 qemu_irq *ioapic_init(void)
 {
-    return ioapic_init_with_arg(NULL, NULL);
+    IOAPICState *s;
+    qemu_irq *irq;
+    ioapic_init_with_arg(IOAPIC_NUM_PINS_DEFAULT, NULL, NULL, &s, &irq);
+    vmstate_register(0, &vmstate_ioapic, s);
+    return irq;
 }
diff --git a/hw/pc.h b/hw/pc.h
index 44eac49..723c478 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -53,7 +53,8 @@ void apic_deliver_pic_intr(CPUState *env, int level);
 int apic_get_interrupt(CPUState *env);
 qemu_irq *ioapic_init(void);
 typedef void (*ioapic_update_fn)(void *opaque, int reset);
-qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque);
+qemu_irq *ioapic_init_with_mre(uint8_t num_pins,
+                               ioapic_update_fn update_fn, void *opaque);
 void apic_reset_irq_delivered(void);
 int apic_get_irq_delivered(void);
 
-- 
1.6.0.2





reply via email to

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