]> Git Repo - qemu.git/blobdiff - hw/apic.c
hda: do not mix output and input stream states, RHBZ #740493
[qemu.git] / hw / apic.c
index 218d1bb6da060ee34b87fc6811cf585f469c1722..8289eef5b83df249a9d7b049e4878b2761f28c81 100644 (file)
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -23,6 +23,7 @@
 #include "host-utils.h"
 #include "sysbus.h"
 #include "trace.h"
+#include "pc.h"
 
 /* APIC Local Vector Table */
 #define APIC_LVT_TIMER   0
@@ -80,6 +81,7 @@ typedef struct APICState APICState;
 
 struct APICState {
     SysBusDevice busdev;
+    MemoryRegion io_memory;
     void *cpu_env;
     uint32_t apicbase;
     uint8_t id;
@@ -222,8 +224,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level)
 }
 
 static void apic_bus_deliver(const uint32_t *deliver_bitmask,
-                             uint8_t delivery_mode,
-                             uint8_t vector_num, uint8_t polarity,
+                             uint8_t delivery_mode, uint8_t vector_num,
                              uint8_t trigger_mode)
 {
     APICState *apic_iter;
@@ -280,18 +281,16 @@ 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)
+void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
+                      uint8_t vector_num, uint8_t trigger_mode)
 {
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
 
     trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num,
-                           polarity, trigger_mode);
+                           trigger_mode);
 
     apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
-    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
-                     trigger_mode);
+    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
 }
 
 void cpu_set_apic_base(DeviceState *d, uint64_t val)
@@ -401,6 +400,9 @@ static void apic_update_irq(APICState *s)
     }
     if (apic_irq_pending(s) > 0) {
         cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+    } else if (apic_accept_pic_intr(&s->busdev.qdev) &&
+               pic_get_output(isa_pic)) {
+        apic_deliver_pic_intr(&s->busdev.qdev, 1);
     }
 }
 
@@ -548,7 +550,7 @@ void apic_sipi(DeviceState *d)
 
 static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
                          uint8_t delivery_mode, uint8_t vector_num,
-                         uint8_t polarity, uint8_t trigger_mode)
+                         uint8_t trigger_mode)
 {
     APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
@@ -591,8 +593,7 @@ static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
             return;
     }
 
-    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
-                     trigger_mode);
+    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
 }
 
 int apic_get_interrupt(DeviceState *d)
@@ -641,7 +642,7 @@ static uint32_t apic_get_current_count(APICState *s)
 {
     int64_t d;
     uint32_t val;
-    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
+    d = (qemu_get_clock_ns(vm_clock) - s->initial_count_load_time) >>
         s->count_shift;
     if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
         /* periodic */
@@ -794,7 +795,7 @@ static void apic_send_msi(target_phys_addr_t addr, uint32_t data)
     uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
     uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
     /* XXX: Ignore redirection hint. */
-    apic_deliver_irq(dest, dest_mode, delivery, vector, 0, trigger_mode);
+    apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode);
 }
 
 static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
@@ -855,7 +856,7 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
         s->icr[0] = val;
         apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
                      (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
-                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
+                     (s->icr[0] >> 15) & 1);
         break;
     case 0x31:
         s->icr[1] = val;
@@ -865,12 +866,12 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
             int n = index - 0x32;
             s->lvt[n] = val;
             if (n == APIC_LVT_TIMER)
-                apic_timer_update(s, qemu_get_clock(vm_clock));
+                apic_timer_update(s, qemu_get_clock_ns(vm_clock));
         }
         break;
     case 0x38:
         s->initial_count = val;
-        s->initial_count_load_time = qemu_get_clock(vm_clock);
+        s->initial_count_load_time = qemu_get_clock_ns(vm_clock);
         apic_timer_update(s, s->initial_count_load_time);
         break;
     case 0x39:
@@ -979,33 +980,27 @@ static void apic_reset(DeviceState *d)
     }
 }
 
-static CPUReadMemoryFunc * const apic_mem_read[3] = {
-    apic_mem_readb,
-    apic_mem_readw,
-    apic_mem_readl,
-};
-
-static CPUWriteMemoryFunc * const apic_mem_write[3] = {
-    apic_mem_writeb,
-    apic_mem_writew,
-    apic_mem_writel,
+static const MemoryRegionOps apic_io_ops = {
+    .old_mmio = {
+        .read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, },
+        .write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int apic_init1(SysBusDevice *dev)
 {
     APICState *s = FROM_SYSBUS(APICState, dev);
-    int apic_io_memory;
     static int last_apic_idx;
 
     if (last_apic_idx >= MAX_APICS) {
         return -1;
     }
-    apic_io_memory = cpu_register_io_memory(apic_mem_read,
-                                            apic_mem_write, NULL,
-                                            DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, MSI_ADDR_SIZE, apic_io_memory);
+    memory_region_init_io(&s->io_memory, &apic_io_ops, s, "apic",
+                          MSI_ADDR_SIZE);
+    sysbus_init_mmio_region(dev, &s->io_memory);
 
-    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
+    s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
     s->idx = last_apic_idx++;
     local_apics[s->idx] = s;
     return 0;
This page took 0.029984 seconds and 4 git commands to generate.