All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Zhang, Xiantao" <xiantao.zhang@intel.com>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Subject: [Qemu-devel] RE: [PATCH] Split ioapic logic from the current apic.
Date: Tue, 3 Mar 2009 13:41:43 +0800	[thread overview]
Message-ID: <706158FABBBA044BAD4FE898A02E4BC22435AE7F@pdsmsx503.ccr.corp.intel.com> (raw)
In-Reply-To: <49A84173.4020509@us.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 615 bytes --]

Hi, Anthony
	I have updated the patch against the latest commits, could you pick it  ? 
Thanks
Xiantao

-----Original Message-----
From: Anthony Liguori [mailto:aliguori@us.ibm.com] 
Sent: Saturday, February 28, 2009 3:40 AM
To: Zhang, Xiantao
Cc: qemu-devel@nongnu.org
Subject: Re: [PATCH] Split ioapic logic from the current apic.

Zhang, Xiantao wrote:
> This patch targets for spliting the ioapic logic from apic.c and make it work for TARGET_IA64, and can be applied to qemu upstream. Thanks!
> Xiantao
>   

This patch doesn't apply against the current SVN.

Regards,

Anthony Liguori


[-- Attachment #2: 0001-Split-ioapic-logic-from-the-current-apic.patch --]
[-- Type: application/octet-stream, Size: 16977 bytes --]

From 67e94ae77f8de4d5d822917f1723cefa7ebfb64d Mon Sep 17 00:00:00 2001
From: Xiantao Zhang <xiantao.zhang@intel.com>
Date: Tue, 3 Mar 2009 13:33:13 +0800
Subject: [PATCH] Split ioapic logic from the current apic.

Add a new ioapic.c to hold ioapic's logic, and also
make it work for ia64.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
---
 Makefile.target |    2 +-
 hw/apic.c       |  237 +++----------------------------------------------
 hw/ioapic.c     |  263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/pc.h         |    5 +-
 4 files changed, 281 insertions(+), 226 deletions(-)
 create mode 100644 hw/ioapic.c

diff --git a/Makefile.target b/Makefile.target
index a091ce9..a4ff10a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -578,7 +578,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
 OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
 OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
-OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
+OBJS+= cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 endif
diff --git a/hw/apic.c b/hw/apic.c
index 3052843..80b6de2 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -23,7 +23,6 @@
 #include "host-utils.h"
 
 //#define DEBUG_APIC
-//#define DEBUG_IOAPIC
 
 /* APIC Local Vector Table */
 #define APIC_LVT_TIMER   0
@@ -57,8 +56,6 @@
 #define	APIC_INPUT_POLARITY		(1<<13)
 #define	APIC_SEND_PENDING		(1<<12)
 
-#define IOAPIC_NUM_PINS			0x18
-
 #define ESR_ILLEGAL_ADDRESS (1 << 7)
 
 #define APIC_SV_ENABLE (1 << 8)
@@ -89,14 +86,6 @@ typedef struct APICState {
     QEMUTimer *timer;
 } APICState;
 
-struct IOAPICState {
-    uint8_t id;
-    uint8_t ioregsel;
-
-    uint32_t irr;
-    uint64_t ioredtbl[IOAPIC_NUM_PINS];
-};
-
 static int apic_io_memory;
 static APICState *local_apics[MAX_APICS + 1];
 static int last_apic_id = 0;
@@ -106,6 +95,8 @@ static int apic_irq_delivered;
 static void apic_init_ipi(APICState *s);
 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
 static void apic_update_irq(APICState *s);
+static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
+                                      uint8_t dest, uint8_t dest_mode);
 
 /* Find first bit starting from msb */
 static int fls_bit(uint32_t value)
@@ -272,6 +263,17 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
                  apic_set_irq(apic_iter, vector_num, trigger_mode) );
 }
 
+void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
+                      uint8_t delivery_mode, uint8_t vector_num,
+                      uint8_t polarity, uint8_t trigger_mode)
+{
+    uint32_t deliver_bitmask[MAX_APIC_WORDS];
+
+    apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
+    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
+                     trigger_mode);
+}
+
 void cpu_set_apic_base(CPUState *env, uint64_t val)
 {
     APICState *s = env->apic_state;
@@ -925,216 +927,3 @@ int apic_init(CPUState *env)
     return 0;
 }
 
-static void ioapic_service(IOAPICState *s)
-{
-    uint8_t i;
-    uint8_t trig_mode;
-    uint8_t vector;
-    uint8_t delivery_mode;
-    uint32_t mask;
-    uint64_t entry;
-    uint8_t dest;
-    uint8_t dest_mode;
-    uint8_t polarity;
-    uint32_t deliver_bitmask[MAX_APIC_WORDS];
-
-    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-        mask = 1 << i;
-        if (s->irr & mask) {
-            entry = s->ioredtbl[i];
-            if (!(entry & APIC_LVT_MASKED)) {
-                trig_mode = ((entry >> 15) & 1);
-                dest = entry >> 56;
-                dest_mode = (entry >> 11) & 1;
-                delivery_mode = (entry >> 8) & 7;
-                polarity = (entry >> 13) & 1;
-                if (trig_mode == APIC_TRIGGER_EDGE)
-                    s->irr &= ~mask;
-                if (delivery_mode == APIC_DM_EXTINT)
-                    vector = pic_read_irq(isa_pic);
-                else
-                    vector = entry & 0xff;
-
-                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
-                apic_bus_deliver(deliver_bitmask, delivery_mode,
-                                 vector, polarity, trig_mode);
-            }
-        }
-    }
-}
-
-void ioapic_set_irq(void *opaque, int vector, int level)
-{
-    IOAPICState *s = opaque;
-
-    /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
-     * to GSI 2.  GSI maps to ioapic 1-1.  This is not
-     * the cleanest way of doing it but it should work. */
-
-    if (vector == 0)
-        vector = 2;
-
-    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
-        uint32_t mask = 1 << vector;
-        uint64_t entry = s->ioredtbl[vector];
-
-        if ((entry >> 15) & 1) {
-            /* level triggered */
-            if (level) {
-                s->irr |= mask;
-                ioapic_service(s);
-            } else {
-                s->irr &= ~mask;
-            }
-        } else {
-            /* edge triggered */
-            if (level) {
-                s->irr |= mask;
-                ioapic_service(s);
-            }
-        }
-    }
-}
-
-static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    IOAPICState *s = opaque;
-    int index;
-    uint32_t val = 0;
-
-    addr &= 0xff;
-    if (addr == 0x00) {
-        val = s->ioregsel;
-    } else if (addr == 0x10) {
-        switch (s->ioregsel) {
-            case 0x00:
-                val = s->id << 24;
-                break;
-            case 0x01:
-                val = 0x11 | ((IOAPIC_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 (s->ioregsel & 1)
-                        val = s->ioredtbl[index] >> 32;
-                    else
-                        val = s->ioredtbl[index] & 0xffffffff;
-                }
-        }
-#ifdef DEBUG_IOAPIC
-        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
-#endif
-    }
-    return val;
-}
-
-static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    IOAPICState *s = opaque;
-    int index;
-
-    addr &= 0xff;
-    if (addr == 0x00)  {
-        s->ioregsel = val;
-        return;
-    } else if (addr == 0x10) {
-#ifdef DEBUG_IOAPIC
-        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
-#endif
-        switch (s->ioregsel) {
-            case 0x00:
-                s->id = (val >> 24) & 0xff;
-                return;
-            case 0x01:
-            case 0x02:
-                return;
-            default:
-                index = (s->ioregsel - 0x10) >> 1;
-                if (index >= 0 && index < IOAPIC_NUM_PINS) {
-                    if (s->ioregsel & 1) {
-                        s->ioredtbl[index] &= 0xffffffff;
-                        s->ioredtbl[index] |= (uint64_t)val << 32;
-                    } else {
-                        s->ioredtbl[index] &= ~0xffffffffULL;
-                        s->ioredtbl[index] |= val;
-                    }
-                    ioapic_service(s);
-                }
-        }
-    }
-}
-
-static void ioapic_save(QEMUFile *f, void *opaque)
-{
-    IOAPICState *s = opaque;
-    int i;
-
-    qemu_put_8s(f, &s->id);
-    qemu_put_8s(f, &s->ioregsel);
-    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-        qemu_put_be64s(f, &s->ioredtbl[i]);
-    }
-}
-
-static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
-{
-    IOAPICState *s = opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    qemu_get_8s(f, &s->id);
-    qemu_get_8s(f, &s->ioregsel);
-    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-        qemu_get_be64s(f, &s->ioredtbl[i]);
-    }
-    return 0;
-}
-
-static void ioapic_reset(void *opaque)
-{
-    IOAPICState *s = opaque;
-    int i;
-
-    memset(s, 0, sizeof(*s));
-    for(i = 0; i < IOAPIC_NUM_PINS; i++)
-        s->ioredtbl[i] = 1 << 16; /* mask LVT */
-}
-
-static CPUReadMemoryFunc *ioapic_mem_read[3] = {
-    ioapic_mem_readl,
-    ioapic_mem_readl,
-    ioapic_mem_readl,
-};
-
-static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
-    ioapic_mem_writel,
-    ioapic_mem_writel,
-    ioapic_mem_writel,
-};
-
-IOAPICState *ioapic_init(void)
-{
-    IOAPICState *s;
-    int io_memory;
-
-    s = qemu_mallocz(sizeof(IOAPICState));
-    if (!s)
-        return NULL;
-    ioapic_reset(s);
-    s->id = last_apic_id++;
-
-    io_memory = cpu_register_io_memory(0, ioapic_mem_read,
-                                       ioapic_mem_write, s);
-    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
-
-    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
-    qemu_register_reset(ioapic_reset, s);
-
-    return s;
-}
diff --git a/hw/ioapic.c b/hw/ioapic.c
new file mode 100644
index 0000000..916e083
--- /dev/null
+++ b/hw/ioapic.c
@@ -0,0 +1,263 @@
+/*
+ *  ioapic.c IOAPIC emulation logic
+ *
+ *  Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ *  Split the ioapic logic from apic.c
+ *  Xiantao Zhang <xiantao.zhang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "qemu-timer.h"
+#include "host-utils.h"
+
+//#define DEBUG_IOAPIC
+
+#define IOAPIC_NUM_PINS			0x18
+#define IOAPIC_LVT_MASKED 		(1<<16)
+
+#define IOAPIC_TRIGGER_EDGE		0
+#define IOAPIC_TRIGGER_LEVEL		1
+
+/*io{apic,sapic} delivery mode*/
+#define IOAPIC_DM_FIXED			0x0
+#define IOAPIC_DM_LOWEST_PRIORITY	0x1
+#define IOAPIC_DM_PMI			0x2
+#define IOAPIC_DM_NMI			0x4
+#define IOAPIC_DM_INIT			0x5
+#define IOAPIC_DM_SIPI			0x5
+#define IOAPIC_DM_EXTINT		0x7
+
+struct IOAPICState {
+    uint8_t id;
+    uint8_t ioregsel;
+
+    uint32_t irr;
+    uint64_t ioredtbl[IOAPIC_NUM_PINS];
+};
+
+static void ioapic_service(IOAPICState *s)
+{
+    uint8_t i;
+    uint8_t trig_mode;
+    uint8_t vector;
+    uint8_t delivery_mode;
+    uint32_t mask;
+    uint64_t entry;
+    uint8_t dest;
+    uint8_t dest_mode;
+    uint8_t polarity;
+
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        mask = 1 << i;
+        if (s->irr & mask) {
+            entry = s->ioredtbl[i];
+            if (!(entry & IOAPIC_LVT_MASKED)) {
+                trig_mode = ((entry >> 15) & 1);
+                dest = entry >> 56;
+                dest_mode = (entry >> 11) & 1;
+                delivery_mode = (entry >> 8) & 7;
+                polarity = (entry >> 13) & 1;
+                if (trig_mode == IOAPIC_TRIGGER_EDGE)
+                    s->irr &= ~mask;
+                if (delivery_mode == IOAPIC_DM_EXTINT)
+                    vector = pic_read_irq(isa_pic);
+                else
+                    vector = entry & 0xff;
+
+                apic_deliver_irq(dest, dest_mode, delivery_mode,
+                                 vector, polarity, trig_mode);
+            }
+        }
+    }
+}
+
+void ioapic_set_irq(void *opaque, int vector, int level)
+{
+    IOAPICState *s = opaque;
+
+    /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
+     * to GSI 2.  GSI maps to ioapic 1-1.  This is not
+     * the cleanest way of doing it but it should work. */
+
+    if (vector == 0)
+        vector = 2;
+
+    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
+        uint32_t mask = 1 << vector;
+        uint64_t entry = s->ioredtbl[vector];
+
+        if ((entry >> 15) & 1) {
+            /* level triggered */
+            if (level) {
+                s->irr |= mask;
+                ioapic_service(s);
+            } else {
+                s->irr &= ~mask;
+            }
+        } else {
+            /* edge triggered */
+            if (level) {
+                s->irr |= mask;
+                ioapic_service(s);
+            }
+        }
+    }
+}
+
+static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    IOAPICState *s = opaque;
+    int index;
+    uint32_t val = 0;
+
+    addr &= 0xff;
+    if (addr == 0x00) {
+        val = s->ioregsel;
+    } else if (addr == 0x10) {
+        switch (s->ioregsel) {
+            case 0x00:
+                val = s->id << 24;
+                break;
+            case 0x01:
+                val = 0x11 | ((IOAPIC_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 (s->ioregsel & 1)
+                        val = s->ioredtbl[index] >> 32;
+                    else
+                        val = s->ioredtbl[index] & 0xffffffff;
+                }
+        }
+#ifdef DEBUG_IOAPIC
+        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
+#endif
+    }
+    return val;
+}
+
+static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    IOAPICState *s = opaque;
+    int index;
+
+    addr &= 0xff;
+    if (addr == 0x00)  {
+        s->ioregsel = val;
+        return;
+    } else if (addr == 0x10) {
+#ifdef DEBUG_IOAPIC
+        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
+#endif
+        switch (s->ioregsel) {
+            case 0x00:
+                s->id = (val >> 24) & 0xff;
+                return;
+            case 0x01:
+            case 0x02:
+                return;
+            default:
+                index = (s->ioregsel - 0x10) >> 1;
+                if (index >= 0 && index < IOAPIC_NUM_PINS) {
+                    if (s->ioregsel & 1) {
+                        s->ioredtbl[index] &= 0xffffffff;
+                        s->ioredtbl[index] |= (uint64_t)val << 32;
+                    } else {
+                        s->ioredtbl[index] &= ~0xffffffffULL;
+                        s->ioredtbl[index] |= val;
+                    }
+                    ioapic_service(s);
+                }
+        }
+    }
+}
+
+static void ioapic_save(QEMUFile *f, void *opaque)
+{
+    IOAPICState *s = opaque;
+    int i;
+
+    qemu_put_8s(f, &s->id);
+    qemu_put_8s(f, &s->ioregsel);
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        qemu_put_be64s(f, &s->ioredtbl[i]);
+    }
+}
+
+static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
+{
+    IOAPICState *s = opaque;
+    int i;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_8s(f, &s->id);
+    qemu_get_8s(f, &s->ioregsel);
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        qemu_get_be64s(f, &s->ioredtbl[i]);
+    }
+    return 0;
+}
+
+static void ioapic_reset(void *opaque)
+{
+    IOAPICState *s = opaque;
+    int i;
+
+    memset(s, 0, sizeof(*s));
+    for(i = 0; i < IOAPIC_NUM_PINS; i++)
+        s->ioredtbl[i] = 1 << 16; /* mask LVT */
+}
+
+static CPUReadMemoryFunc *ioapic_mem_read[3] = {
+    ioapic_mem_readl,
+    ioapic_mem_readl,
+    ioapic_mem_readl,
+};
+
+static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
+    ioapic_mem_writel,
+    ioapic_mem_writel,
+    ioapic_mem_writel,
+};
+
+IOAPICState *ioapic_init(void)
+{
+    IOAPICState *s;
+    int io_memory;
+
+    s = qemu_mallocz(sizeof(IOAPICState));
+    if (!s)
+        return NULL;
+    ioapic_reset(s);
+
+    io_memory = cpu_register_io_memory(0, ioapic_mem_read,
+                                       ioapic_mem_write, s);
+    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
+
+    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
+    qemu_register_reset(ioapic_reset, s);
+
+    return s;
+}
diff --git a/hw/pc.h b/hw/pc.h
index c67294d..d05553d 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -39,7 +39,10 @@ void irq_info(void);
 
 /* APIC */
 typedef struct IOAPICState IOAPICState;
-
+void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
+                             uint8_t delivery_mode,
+                             uint8_t vector_num, uint8_t polarity,
+                             uint8_t trigger_mode);
 int apic_init(CPUState *env);
 int apic_accept_pic_intr(CPUState *env);
 void apic_deliver_pic_intr(CPUState *env, int level);
-- 
1.6.0


  reply	other threads:[~2009-03-03  5:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-19  2:30 [Qemu-devel] [PATCH] Split ioapic logic from the current apic Zhang, Xiantao
2009-02-25  9:07 ` [Qemu-devel] " Zhang, Xiantao
2009-02-27 19:39 ` [Qemu-devel] " Anthony Liguori
2009-03-03  5:41   ` Zhang, Xiantao [this message]
2009-03-12 20:25     ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=706158FABBBA044BAD4FE898A02E4BC22435AE7F@pdsmsx503.ccr.corp.intel.com \
    --to=xiantao.zhang@intel.com \
    --cc=aliguori@us.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.