Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


compilable versions of the APIC/ICC_BUS/IOAPIC
Jack Lange [Fri, 15 Jan 2010 23:46:36 +0000 (17:46 -0600)]
palacios/include/devices/icc_bus.h
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/apic.c
palacios/src/devices/icc_bus.c
palacios/src/devices/io_apic.c

index d75aa57..c51f6f8 100644 (file)
 #ifndef ICC_BUS_H_
 #define ICC_BUS_H_
 
+
+struct v3_icc_ops {
+    int (*raise_intr)(struct guest_info * core, int intr_num, void * private_data);
+};
+
+
 /**
  *
  */
-int v3_icc_register_apic(struct v3_vm_info *info, struct vm_device *icc_bus, struct vm_device *apic, uint32_t apic_num);
+int v3_icc_register_apic(struct guest_info * vm, struct vm_device * icc_bus, uint8_t apic_phys_id, struct v3_icc_ops * ops, void * priv_data);
+
 
 /**
  * Send an inter-processor interrupt (IPI) from this local APIC to another local APIC.
  *
- * @param icc_bus The ICC bus that facilitates the communication.
- * @param apic_num The remote APIC number.
- * @param intr_num The interrupt number.
+ * @param icc_bus - The ICC bus that routes IPIs.
+ * @param apic_num - The remote APIC number.
+ * @param intr_num - The interrupt number.
  */
-int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t apic_num, uint32_t intr_num);
+int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num);
+
+
+
 
 #endif /* ICC_BUS_H_ */
index 262dbed..a5847ef 100644 (file)
@@ -1,8 +1,9 @@
 menu "Virtual Devices"
 
 config APIC
-       bool "APIC"
+       bool "APIC" 
        default y
+       depends on ICC_BUS
        help 
          Includes the Virtual APIC device
 
@@ -15,6 +16,29 @@ config DEBUG_APIC
          Enable debugging for the APIC
 
 
+
+config IO_APIC
+       bool "IOAPIC"
+       depends on ICC_BUS
+       default y
+       help 
+         Includes the Virtual IO APIC
+
+config DEBUG_IO_APIC
+       bool "IO APIC Debugging"
+       default n
+       depends on IO_APIC && DEBUG_ON 
+       help 
+         Enable debugging for the IO APIC
+
+
+config ICC_BUS
+       bool "ICC BUS"
+       default y
+       help 
+         The ICC Bus for APIC/IOAPIC communication
+
+
 config BOCHS_DEBUG
        bool "Bochs Debug Console Device"
        default y
@@ -60,20 +84,6 @@ config DEBUG_IDE
          Enable debugging for the IDE Layer
 
 
-config IO_APIC
-       bool "IOAPIC"
-       depends on ICC_BUS
-       default y
-       help 
-         Includes the Virtual IO APIC
-
-config DEBUG_IO_APIC
-       bool "IO APIC Debugging"
-       default n
-       depends on IO_APIC && DEBUG_ON 
-       help 
-         Enable debugging for the IO APIC
-
 
 
 
index a9b7f54..88c5706 100644 (file)
@@ -1,11 +1,13 @@
 obj-$(CONFIG_APIC) += apic.o
+obj-$(CONFIG_IO_APIC) += io_apic.o
+obj-$(CONFIG_ICC_BUS) += icc_bus.o
 obj-$(CONFIG_PIT) += 8254.o
 obj-$(CONFIG_PIC) += 8259a.o
 obj-$(CONFIG_BOCHS_DEBUG) += bochs_debug.o
 obj-$(CONFIG_GENERIC) += generic.o
 obj-$(CONFIG_I440FX) += i440fx.o
 obj-$(CONFIG_IDE) += ide.o
-obj-$(CONFIG_IO_APIC) += io_apic.o
+
 obj-$(CONFIG_KEYBOARD) += keyboard.o
 obj-$(CONFIG_LINUX_VIRTIO_BALLOON) += lnx_virtio_balloon.o
 obj-$(CONFIG_LINUX_VIRTIO_BLOCK) += lnx_virtio_blk.o
index f45e7b8..7aea038 100644 (file)
 
 #include <devices/apic.h>
 #include <devices/apic_regs.h>
+#include <devices/icc_bus.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_msr.h>
 #include <palacios/vmm_sprintf.h>
 #include <palacios/vm_guest.h>
 
+
 #ifndef CONFIG_DEBUG_APIC
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
@@ -181,14 +183,13 @@ struct apic_state {
   
     uint32_t eoi;
 
-    uint32_t my_apic_id;
-    struct vm_device *icc_bus;
+    struct vm_device * icc_bus;
 
     v3_lock_t  lock;
 };
 
-static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data);
-static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data);
+static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data);
+static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data);
 
 static void init_apic_state(struct apic_state * apic) {
     apic->base_addr = DEFAULT_BASE_ADDR;
@@ -241,9 +242,11 @@ static void init_apic_state(struct apic_state * apic) {
 
 
 
-static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
+static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apics = (struct apic_state *)(dev->private_data);
+    struct apic_state * apic = &(apics[core->cpu_id]);
+
     v3_lock(apic->lock);
     dst->value = apic->base_addr;
     v3_unlock(apic->lock);
@@ -251,10 +254,11 @@ static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
 }
 
 
-static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
+static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
-    struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, apic->base_addr);
+    struct apic_state * apics = (struct apic_state *)(dev->private_data);
+    struct apic_state * apic = &(apics[core->cpu_id]);
+    struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, core->cpu_id, apic->base_addr);
 
 
     if (old_reg == NULL) {
@@ -269,7 +273,7 @@ static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
 
     apic->base_addr = src.value;
 
-    if (v3_hook_full_mem(dev->vm, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev) == -1) {
+    if (v3_hook_full_mem(dev->vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev) == -1) {
        PrintError("Could not hook new APIC Base address\n");
        v3_unlock(apic->lock);
        return -1;
@@ -446,9 +450,8 @@ static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_t
 }
 
 
-static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+    struct apic_state * apic = (struct apic_state *)priv_data;
     addr_t reg_addr  = guest_addr - apic->base_addr;
     struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value);
     uint32_t val = 0;
@@ -705,9 +708,8 @@ static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_d
 /**
  *
  */
-static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) {
+    struct apic_state * apic = (struct apic_state *)priv_data;
     addr_t reg_addr  = guest_addr - apic->base_addr;
     struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value);
     uint32_t op_val = *(uint32_t *)src;
@@ -861,7 +863,8 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
 
        case INT_CMD_LO_OFFSET:
            apic->int_cmd.lo = op_val;
-        v3_icc_send_ipi(apic->icc_bus, apic->int_cmd.dst, apic->int_cmd.val);
+           // ICC???
+           v3_icc_send_irq(apic->icc_bus, apic->int_cmd.dst, apic->int_cmd.val);
            break;
        case INT_CMD_HI_OFFSET:
            apic->int_cmd.hi = op_val;
@@ -886,8 +889,7 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
 
 // returns 1 if an interrupt is pending, 0 otherwise
 static int apic_intr_pending(struct guest_info * info, void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -900,8 +902,7 @@ static int apic_intr_pending(struct guest_info * info, void * private_data) {
 }
 
 static int apic_get_intr_number(struct guest_info * info, void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -914,30 +915,17 @@ static int apic_get_intr_number(struct guest_info * info, void * private_data) {
     return -1;
 }
 
-#if 0
-static int apic_raise_intr(struct guest_info * info, void * private_data, int irq) {
-#ifdef CONFIG_CRAY_XT
-    // The Seastar is connected directly to the LAPIC via LINT0 on the ICC bus
-
-    if (irq == 238) {
-       struct vm_device * dev = (struct vm_device *)private_data;
-       struct apic_state * apic = (struct apic_state *)dev->private_data;
 
-       return activate_apic_irq(apic, irq);
-    }
-#endif
+static int apic_raise_intr(struct guest_info * info, int irq, void * private_data) {
+  struct apic_state * apic = (struct apic_state *)private_data;
 
-    return 0;
+  return activate_apic_irq(apic, irq);
 }
 
-static int apic_lower_intr(struct guest_info * info, void * private_data, int irq) {
-    return 0;
-}
-#endif
+
 
 static int apic_begin_irq(struct guest_info * info, void * private_data, int irq) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)private_data;
     int major_offset = (irq & ~0x00000007) >> 3;
     int minor_offset = irq & 0x00000007;
     uchar_t * req_location = apic->int_req_reg + major_offset;
@@ -947,41 +935,17 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
     *svc_location |= flag;
     *req_location &= ~flag;
 
-#ifdef CONFIG_CRAY_XT
-    if ((irq == 238) || (irq == 239)) {
-       PrintError("APIC: Begin IRQ %d (ISR=%x), (IRR=%x)\n", irq, *svc_location, *req_location);
-    }
-#endif
-
-    return 0;
-}
-
-
-
-int v3_apic_raise_intr(struct guest_info * info, struct vm_device * apic_dev, int intr_num) {
-    struct apic_state * apic = (struct apic_state *)apic_dev->private_data;
-
-    // Special cases go here
-    // startup, etc
-
-    if (activate_apic_irq(apic, intr_num) == -1) {
-       PrintError("Error: Could not activate apic_irq\n");
-       return -1;
-    } 
 
-    // Don't need this since we'll have the IPI force an exit if
-    // This is called on a different core
-    /* v3_interrupt_cpu(info, 0); */
 
     return 0;
 }
 
 
 
+
 /* Timer Functions */
 static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data) {
-    struct vm_device * dev = (struct vm_device *)priv_data;
-    struct apic_state * apic = (struct apic_state *)dev->private_data;
+    struct apic_state * apic = (struct apic_state *)priv_data;
     // The 32 bit GCC runtime is a pile of shit
 #ifdef __V3_64BIT__
     uint64_t tmr_ticks = 0;
@@ -1097,19 +1061,27 @@ static struct v3_device_ops dev_ops = {
 
 
 
+static struct v3_icc_ops icc_ops = {
+    .raise_intr = apic_raise_intr,
+};
+
+
+
 static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("Creating APIC\n");
     char * name = v3_cfg_val(cfg, "name");
     char * icc_name = v3_cfg_val(cfg,"irq_bus");
-    int i;
     struct vm_device * icc = v3_find_dev(vm, icc_name);
+    int i;
 
     if (!icc) {
-        PrintError("Cannot find device %s\n", icc_name);
+        PrintError("Cannot find ICC Bus (%s)\n", icc_name);
         return -1;
     }
 
-    struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state));
+    // We allocate one apic per core
+    // APICs are accessed via index which correlates with the core's cpu_id 
+    struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state) * vm->num_cores);
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, apic);
 
@@ -1118,20 +1090,23 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
        return -1;
     }
 
-    for (i = 0; i < vm->num_cores; i++)
-    {
-       v3_register_intr_controller(&vm->cores[i], &intr_ops, dev);
-       v3_add_timer(&vm->cores[i], &timer_ops, dev);
+    
+    for (i = 0; i < vm->num_cores; i++) {
+       struct guest_info * core = &(vm->cores[i]);
+
+       v3_register_intr_controller(core, &intr_ops, &(apic[i]));
+       v3_add_timer(core, &timer_ops, &(apic[i]));
+       v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, &(apic[i]));
+
+       v3_icc_register_apic(core, icc, i, &icc_ops, &(apic[i]));
+
+       init_apic_state(&(apic[i]));
     }
 
-    init_apic_state(apic);
 
-    v3_icc_register_apic(vm, icc, dev,apic->my_apic_id);
 
     v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
 
-    v3_hook_full_mem(vm, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev);
-
     return 0;
 }
 
index fe76cff..f5de549 100644 (file)
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_sprintf.h>
 #include <palacios/vm_guest.h>
-#include <devices/apic_regs.h>
-#include <devices/apic.h>
+#include <devices/icc_bus.h>
 
-#define MAX_APIC 256
+#define MAX_APICS 256
 
-struct icc_bus_internal {
-    struct vm_device * apic[MAX_APIC];
+
+struct ipi_thunk_data {
+    struct vm_device * target;
+    uint64_t val;
+};
+
+struct int_cmd_reg {
+    union {
+        uint64_t val;
+
+        struct {
+            uint32_t lo;
+            uint32_t hi;
+        } __attribute__((packed));
+
+        struct {
+            uint_t vec           : 8;
+            uint_t msg_type      : 3;
+            uint_t dst_mode      : 1;
+            uint_t del_status    : 1;
+            uint_t rsvd1         : 1;
+            uint_t lvl           : 1;
+            uint_t trig_mode     : 1;
+            uint_t rem_rd_status : 2;
+            uint_t dst_shorthand : 2;
+            uint64_t rsvd2       : 36;
+            uint32_t dst         : 8;
+        } __attribute__((packed));
+    } __attribute__((packed));
+} __attribute__((packed));
+
+
+
+
+struct apic_data {
+    struct guest_info * core;
+    struct v3_icc_ops * ops;
+    
+    void * priv_data;
+    int present;
+};
+
+
+struct icc_bus_state {
+    struct apic_data apics[MAX_APICS];
 };
 
 static struct v3_device_ops dev_ops = {
@@ -36,98 +78,98 @@ static struct v3_device_ops dev_ops = {
     .stop = NULL,
 };
 
-int v3_icc_register_apic(struct v3_vm_info *info, struct vm_device *icc_bus, struct vm_device *apic, uint32_t apic_num)
-{
-    struct icc_bus_internal * icc = (struct icc_bus_internal *)icc_bus->private_data;
-
-    if (apic_num < MAX_APIC) {
-        if (icc->apic[apic_num]) {
-            PrintError("Attempt to re-register apic %u\n", apic_num);
-            return -1;
-        } else {
-            icc->apic[apic_num] = apic;
-            PrintDebug("Registered apic or ioapic %u\n", apic_num);
-            return 0;
-        }
-    } else {
-        PrintError("Too many apics for icc bus!");
-        return -1;
-    }
-}
 
-struct ipi_thunk_data {
-    struct vm_device *target;
-    uint64_t          val;
-} ;
 
-static void icc_force_exit(void *val)
-{
-     return;
-}
 
-int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t apic_num, uint32_t val) {
-    struct icc_bus_internal * internal = (struct icc_bus_internal *)icc_bus->private_data;
+int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num) {
+    struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data;
+    struct apic_data * apic = &(state->apics[apic_num]);    
+
 
     struct int_cmd_reg icr;
-    icr.lo = val;
+    icr.lo = irq_num;
 
-    char *type = NULL, *dest = NULL;
+
+    char * type = NULL;
+    char * dest = NULL;
     char foo[8];
 
-    switch (icr.dst_shorthand)
-    {
-    case 0x0:
-        sprintf(foo, "%d", icr.dst);
-        dest = foo;
-        break;
-    case 0x1:
-        dest = "(self)";
-        break;
-    case 0x2:
-        dest = "(broadcast inclusive)";
-        break;
-    case 0x3:
-        dest = "(broadcast)";
-        break;
+    switch (icr.dst_shorthand) {
+       case 0x0:
+           sprintf(foo, "%d", icr.dst);
+           dest = foo;
+           break;
+       case 0x1:
+           dest = "(self)";
+           break;
+       case 0x2:
+           dest = "(broadcast inclusive)";
+           break;
+       case 0x3:
+           dest = "(broadcast)";
+           break;
     }
-    switch (icr.msg_type)
-    {
-    case 0x0:
-        type = "";
-        break;
-    case 0x4:
-        type = "(NMI)";
-        break;
-    case 0x5:
-        type = "(INIT)";
-        break;
-    case 0x6:
-        type = "(Startup)";
-        break;
+
+    switch (icr.msg_type) {
+       case 0x0:
+           type = "";
+           break;
+       case 0x4:
+           type = "(NMI)";
+           break;
+       case 0x5:
+           type = "(INIT)";
+           break;
+       case 0x6:
+           type = "(Startup)";
+           break;
     }
 
 
-    PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n", type, dest, V3_Get_CPU(), apic_num);
+    PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n", 
+              type, dest, V3_Get_CPU(), apic_num);
 
-    v3_apic_raise_intr(internal->apic[apic_num], val & 0xff);
+    apic->ops->raise_intr(apic->core, irq_num & 0xff, apic->priv_data);
 
-    V3_Call_On_CPU(apic_num,  icc_force_exit, (void *)(uint64_t)(val & 0xff));
+    //V3_Call_On_CPU(apic_num,  icc_force_exit, (void *)(uint64_t)(val & 0xff));
 
     return 0;
 }
 
 
-static int init_icc_bus_internal_state(struct icc_bus_internal* icc) {
-    int i;
-    for (i=0;i<MAX_APIC;i++) { icc->apic[i]=0; }
-    return  0;
+
+/* THIS IS A BIG ASSUMPTION: APIC PHYSID == LOGID == CORENUM */
+
+int v3_icc_register_apic(struct guest_info  * core, struct vm_device * icc_bus, 
+                        uint8_t apic_num, struct v3_icc_ops * ops, void * priv_data) {
+    struct icc_bus_state * icc = (struct icc_bus_state *)icc_bus->private_data;
+    struct apic_data * apic = &(icc->apics[apic_num]);
+
+    if (apic->present == 1) {
+       PrintError("Attempt to re-register apic %u\n", apic_num);
+       return -1;
+    }
+    
+    apic->present = 1;
+    apic->priv_data = priv_data;
+    apic->core = core;
+    apic->ops = ops;
+   
+    PrintDebug("Registered apic%u\n", apic_num);
+
+    return 0;
 }
 
+
+
+
 static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("Creating ICC_BUS\n");
+
     char * name = v3_cfg_val(cfg, "name");
 
-    struct icc_bus_internal * icc_bus = (struct icc_bus_internal *)V3_Malloc(sizeof(struct icc_bus_internal));
+    struct icc_bus_state * icc_bus = (struct icc_bus_state *)V3_Malloc(sizeof(struct icc_bus_state));
+    memset(icc_bus, 0, sizeof(struct icc_bus_state));
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, icc_bus);
 
@@ -136,8 +178,6 @@ static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
         return -1;
     }
 
-    init_icc_bus_internal_state(icc_bus);
-
     return 0;
 }
 
index dce46dd..be69bbc 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
-#include <devices/apic.h>
+#include <devices/icc_bus.h>
 #include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_IO_APIC
@@ -135,8 +135,7 @@ struct io_apic_state {
   
     struct redir_tbl_entry redir_tbl[24];
 
-    // This is a temporary method of communication between the IOAPIC and the LAPIC
-    struct vm_device * apic;
+    struct vm_device * icc_bus;
   
 };
 
@@ -158,7 +157,7 @@ static void init_ioapic_state(struct io_apic_state * ioapic) {
 }
 
 
-static int ioapic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+static int ioapic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
@@ -202,7 +201,7 @@ static int ioapic_read(addr_t guest_addr, void * dst, uint_t length, void * priv
 }
 
 
-static int ioapic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
+static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
@@ -253,21 +252,8 @@ static int ioapic_write(addr_t guest_addr, void * src, uint_t length, void * pri
     return length;
 }
 
-/* Interrupt controller functions */
-static int ioapic_intr_pending(struct guest_info * info, void * private_data) {
-    return 0;
-}
-
-
-static int ioapic_get_intr_number(struct guest_info * info, void * private_data) {
-    return 0;
-}
-
-static int ioapic_begin_irq(struct guest_info * info, void * private_data, int irq) {
-    return 0;
-}
 
-static int ioapic_raise_irq(struct guest_info * info, void * private_data, int irq) {
+static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data);  
     struct redir_tbl_entry * irq_entry = NULL;
@@ -281,23 +267,19 @@ static int ioapic_raise_irq(struct guest_info * info, void * private_data, int i
 
     if (irq_entry->mask == 0) {
        PrintDebug("IOAPIC Signalling APIC to raise INTR %d\n", irq_entry->vec);
-       //v3_apic_raise_intr(info, ioapic->apic, irq_entry->vec);
-       v3_apic_raise_intr(ioapic->apic, irq_entry->vec);
+       v3_icc_send_irq(ioapic->icc_bus, irq_entry->dst_field, irq_entry->vec);
     }
 
     return 0;
 }
 
 /* I don't know if we can do anything here.... */
-static int ioapic_lower_irq(struct guest_info * info, void * private_data, int irq) {
+static int ioapic_lower_irq(struct v3_vm_info * vm, void * private_data, int irq) {
     return 0;
 }
 
-static struct intr_ctrl_ops intr_ops = {
-    .intr_pending = ioapic_intr_pending,
-    .get_intr_number = ioapic_get_intr_number,
+static struct intr_router_ops router_ops = {
     .raise_intr = ioapic_raise_irq,
-    .begin_irq = ioapic_begin_irq,
     .lower_intr = ioapic_lower_irq, 
 };
 
@@ -320,12 +302,12 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
-    struct vm_device * apic = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus"));
+static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * icc_bus = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus"));
     char * name = v3_cfg_val(cfg, "name");
 
-    if (!apic) {
-       PrintError("Could not locate APIC device (%s)\n", v3_cfg_val(cfg, "irq_bus"));
+    if (!icc_bus) {
+       PrintError("Could not locate ICC BUS device (%s)\n", v3_cfg_val(cfg, "irq_bus"));
        return -1;
     }
 
@@ -333,7 +315,7 @@ static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
 
     struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state));
 
-    ioapic->apic = apic;
+    ioapic->icc_bus = icc_bus;
 
     struct vm_device * dev = v3_allocate_device(name, &dev_ops, ioapic);
 
@@ -344,10 +326,10 @@ static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     }
 
 
-    v3_register_intr_controller(vm, &intr_ops, dev);
+    v3_register_intr_router(vm, &router_ops, dev);
     init_ioapic_state(ioapic);
 
-    v3_hook_full_mem(vm, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
+    v3_hook_full_mem(vm, V3_MEM_CORE_ANY, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
                     ioapic_read, ioapic_write, dev);
   
     return 0;