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.


removed icc bus
Jack Lange [Wed, 27 Oct 2010 04:32:40 +0000 (23:32 -0500)]
palacios/include/devices/apic.h
palacios/include/devices/icc_bus.h [deleted file]
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/apic.c
palacios/src/devices/icc_bus.c [deleted file]
palacios/src/devices/io_apic.c

index e4452e7..6ad758e 100644 (file)
@@ -26,7 +26,7 @@
 
 
 
-int v3_apic_raise_intr(struct guest_info * info, struct vm_device * apic_dev, int intr_num);
+int v3_apic_raise_intr(struct v3_vm_info * vm, struct vm_device * apic_dev, uint32_t irq, uint32_t dst);
 
 
 #endif // ! __V3VEE__
diff --git a/palacios/include/devices/icc_bus.h b/palacios/include/devices/icc_bus.h
deleted file mode 100644 (file)
index e9aebbd..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico.  You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#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 (*should_deliver)(struct guest_info * core, uint8_t mda, void * private_data);
-};
-
-
-/**
- *
- */
-int v3_icc_register_apic(struct guest_info *core, struct vm_device * icc_bus, uint8_t apic_phys_id, struct v3_icc_ops * ops, void * priv_data);
-int v3_icc_register_ioapic(struct v3_vm_info *vm, struct vm_device * icc_bus, uint8_t apic_phys_id);
-
-/**
- * Send an inter-processor interrupt (IPI) from one local APIC to another local APIC.
- *
- * @param icc_bus  - The ICC bus that routes IPIs.
- * @param apic_src - The source APIC id.
- * @param apic_num - The remote APIC number.
- * @param icr      - A copy of the APIC's ICR.  (LAPIC-style ICR, clone from redir table for ioapics)
- * @param dfr      - A copy of the APIC's DFR   (LAPIC-style DFR)
- & @param extirq   - irq for external interrupts (e.g., from 8259)
- */
-int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t apic_src, uint64_t icr, uint32_t ext_irq);
-
-
-#if 0
-/**
- * Send an IRQinter-processor interrupt (IPI) from one local APIC to another local APIC.
- *
- * @param icc_bus  - The ICC bus that routes IPIs.
- * @param apic_src - The source APIC id.
- * @param apic_num - The remote APIC number.
- * @param icrlo    - The low 32 bites of the APIC's ICR.
- */
-int v3_icc_send_irq(struct vm_device * icc_bus, uint32_t ioapic_src, uint8_t apic_num, uint8_t irq);
-
-#endif
-
-
-#endif /* ICC_BUS_H_ */
index 7bcc256..7185263 100644 (file)
@@ -3,7 +3,7 @@ menu "Virtual Devices"
 config APIC
        bool "APIC" 
        default y
-       depends on ICC_BUS && EXPERIMENTAL
+       depends on EXPERIMENTAL
        help 
          Includes the Virtual APIC device
 
@@ -19,7 +19,7 @@ config DEBUG_APIC
 
 config IO_APIC
        bool "IOAPIC"
-       depends on ICC_BUS && EXPERIMENTAL
+       depends on EXPERIMENTAL
        default y
        help 
          Includes the Virtual IO APIC
@@ -32,20 +32,6 @@ config DEBUG_IO_APIC
          Enable debugging for the IO APIC
 
 
-config ICC_BUS
-       bool "ICC BUS"
-       default y
-       depends on EXPERIMENTAL
-       help 
-         The ICC Bus for APIC/IOAPIC communication
-
-config DEBUG_ICC_BUS
-       bool "ICC BUS Debugging"
-       default n
-       depends on ICC_BUS && DEBUG_ON
-       help
-         Enable debugging for the ICC BUS
-
 
 config BOCHS_DEBUG
        bool "Bochs Debug Console Device"
index 817645d..7ed99be 100644 (file)
@@ -1,6 +1,5 @@
 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
index 0254d67..d439e25 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>
+#include <palacios/vmm_types.h>
 
 
 #ifndef CONFIG_DEBUG_APIC
@@ -138,6 +138,8 @@ struct apic_msr {
 
 typedef enum {INIT, SIPI, STARTED} ipi_state_t; 
 
+struct apic_dev_state;
+
 struct apic_state {
     addr_t base_addr;
 
@@ -185,10 +187,10 @@ struct apic_state {
     uint8_t int_svc_reg[32];
     uint8_t int_en_reg[32];
     uint8_t trig_mode_reg[32];
-  
-    uint32_t eoi;
 
-    struct vm_device * icc_bus;
+    struct guest_info * core;
+
+    uint32_t eoi;
 
     v3_lock_t  lock;
 };
@@ -196,11 +198,18 @@ struct apic_state {
 
 
 
+struct apic_dev_state {
+    int num_apics;
+
+    struct apic_state apics[0];
+} __attribute__((packed));
+
+
 
 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, uint32_t id, struct vm_device * icc) {
+static void init_apic_state(struct apic_state * apic, uint32_t id) {
     apic->base_addr = DEFAULT_BASE_ADDR;
 
     if (id == 0) { 
@@ -231,8 +240,6 @@ static void init_apic_state(struct apic_state * apic, uint32_t id, struct vm_dev
 
     apic->lapic_id.val = id;
     
-    apic->icc_bus = icc;
-
     apic->ipi_state = INIT;
 
     // The P6 has 6 LVT entries, so we set the value to (6-1)...
@@ -265,9 +272,8 @@ static void init_apic_state(struct apic_state * apic, uint32_t id, struct vm_dev
 
 
 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 * apics = (struct apic_state *)(dev->private_data);
-    struct apic_state * apic = &(apics[core->cpu_id]);
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)priv_data;
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]);
 
     PrintDebug("apic %u: core %u: MSR read\n", apic->lapic_id.val, core->cpu_id);
     v3_lock(apic->lock);
@@ -278,13 +284,12 @@ static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, v
 
 
 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 * apics = (struct apic_state *)(dev->private_data);
-    struct apic_state * apic = &(apics[core->cpu_id]);
-    struct v3_mem_region * old_reg = v3_get_mem_region(dev->vm, core->cpu_id, apic->base_addr);
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)priv_data;
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]);
+    struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->cpu_id, apic->base_addr);
 
 
-    PrintDebug("apic %u: core %u: MSR write\n",apic->lapic_id.val,core->cpu_id);
+    PrintDebug("apic %u: core %u: MSR write\n", apic->lapic_id.val, core->cpu_id);
 
     if (old_reg == NULL) {
        // uh oh...
@@ -295,11 +300,11 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo
     
     v3_lock(apic->lock);
 
-    v3_delete_mem_region(dev->vm, old_reg);
+    v3_delete_mem_region(core->vm_info, old_reg);
 
     apic->base_addr = src.value;
 
-    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) {
+    if (v3_hook_full_mem(core->vm_info, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev) == -1) {
        PrintError("apic %u: core %u: Could not hook new APIC Base address\n",
                   apic->lapic_id.val, core->cpu_id);
        v3_unlock(apic->lock);
@@ -481,8 +486,291 @@ static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_t
 }
 
 
+
+static inline int should_deliver_cluster_ipi(struct guest_info * dst_core, 
+                                            struct apic_state * dst_apic, uint8_t mda) {
+
+    if         ( ((mda & 0xf0) == (dst_apic->log_dst.dst_log_id & 0xf0)) &&     // (I am in the cluster and
+         ((mda & 0x0f) & (dst_apic->log_dst.dst_log_id & 0x0f)) ) {  //  I am in the set)
+
+       PrintDebug("apic %u core %u: accepting clustered IRQ (mda 0x%x == log_dst 0x%x)\n",
+                  dst_apic->lapic_id.val, dst_core->cpu_id, mda, 
+                  dst_apic->log_dst.dst_log_id);
+       
+       return 1;
+    } else {
+       PrintDebug("apic %u core %u: rejecting clustered IRQ (mda 0x%x != log_dst 0x%x)\n",
+                  dst_apic->lapic_id.val, dst_core->cpu_id, mda, dst_
+                  dst_apic->log_dst.dst_log_id);
+       return 0;
+    }
+}
+
+static inline int should_deliver_flat_ipi(struct guest_info * dst_core,
+                                         struct apic_state * dst_apic, uint8_t mda) {
+
+    if (dst_apic->log_dst.dst_log_id & mda) {  // I am in the set 
+
+       PrintDebug("apic %u core %u: accepting flat IRQ (mda 0x%x == log_dst 0x%x)\n",
+                  dst_apic->lapic_id.val, dst_core->cpu_id, mda, 
+                  dst_apic->log_dst.dst_log_id);
+      return 1;
+  } else {
+       PrintDebug("apic %u core %u: rejecting flat IRQ (mda 0x%x != log_dst 0x%x)\n",
+                  dst_apic->lapic_id.val, dst_core->cpu_id, mda, 
+                  dst_apic->log_dst.dst_log_id);
+      return 0;
+  }
+}
+
+
+
+static int should_deliver_ipi(struct guest_info * dst_core, 
+                             struct apic_state * dst_apic, uint8_t mda) {
+
+    if (mda == 0xff) {
+       // always deliver broadcast
+       return 1;
+    }
+
+    if (dst_apic->dst_fmt.model == 0xf) {
+       return should_deliver_cluster_ipi(dst_core, dst_apic, mda);
+    } else if (dst_apic->dst_fmt.model == 0x0) {
+       return should_deliver_flat_ipi(dst_core, dst_apic, mda);
+    } else {
+       PrintError("apic %u core %u: invalid destination format register value 0x%x for logical mode delivery.\n", 
+                  dst_apic->lapic_id.val, dst_core->cpu_id, dst_apic->dst_fmt.model);
+       return -1;
+    }
+}
+
+
+static int deliver_ipi(struct guest_info * core, 
+                      struct apic_state * src_apic, 
+                      struct apic_state * dst_apic, 
+                      uint32_t vector, uint8_t del_mode) {
+
+    struct guest_info * dst_core = dst_apic->core;
+
+    switch (del_mode) {
+
+       case 0:  //fixed
+       case 1: // lowest priority
+           PrintDebug("icc_bus: delivering IRQ to core %u\n", dst_core->cpu_id); 
+
+           activate_apic_irq(dst_apic, vector);
+
+           if (dst_apic != src_apic) { 
+               // Assume core # is same as logical processor for now
+               // TODO FIX THIS FIX THIS
+               // THERE SHOULD BE:  guestapicid->virtualapicid map,
+               //                   cpu_id->logical processor map
+               //     host maitains logical proc->phsysical proc
+               PrintDebug("icc_bus: non-local core, forcing it to exit\n"); 
+
+               v3_interrupt_cpu(core->vm_info, dst_core->cpu_id, 0);
+           }
+
+           break;
+       case 5: { //INIT
+
+           PrintDebug("icc_bus: INIT delivery to core %u\n", dst_core->cpu_id);
+
+           // TODO: any APIC reset on dest core (shouldn't be needed, but not sure...)
+
+           // Sanity check
+           if (dst_apic->ipi_state != INIT) { 
+               PrintError("icc_bus: Warning: core %u is not in INIT state (mode = %d), ignored\n",
+                          dst_core->cpu_id, dst_core->cpu_mode);
+               // Only a warning, since INIT INIT SIPI is common
+               break;
+           }
+
+           // We transition the target core to SIPI state
+           dst_apic->ipi_state = SIPI;  // note: locking should not be needed here
+
+           // That should be it since the target core should be
+           // waiting in host on this transition
+           // either it's on another core or on a different preemptive thread
+           // in both cases, it will quickly notice this transition 
+           // in particular, we should not need to force an exit here
+
+           PrintDebug("icc_bus: INIT delivery done\n");
+
+           break;                                                      
+       }
+       case 6: { //SIPI
+
+           // Sanity check
+           if (dst_apic->ipi_state != SIPI) { 
+               PrintError("icc_bus: core %u is not in SIPI state (mode = %d), ignored!\n",
+                          dst_core->cpu_id, dst_core->cpu_mode);
+               break;
+           }
+
+           // Write the RIP, CS, and descriptor
+           // assume the rest is already good to go
+           //
+           // vector VV -> rip at 0
+           //              CS = VV00
+           //  This means we start executing at linear address VV000
+           //
+           // So the selector needs to be VV00
+           // and the base needs to be VV000
+           //
+           dst_core->rip = 0;
+           dst_core->segments.cs.selector = vector << 8;
+           dst_core->segments.cs.limit = 0xffff;
+           dst_core->segments.cs.base = vector << 12;
+
+           PrintDebug("icc_bus: SIPI delivery (0x%x -> 0x%x:0x0) to core %u\n",
+                      vec, dst_core->segments.cs.selector, dst_core->cpu_id);
+           // Maybe need to adjust the APIC?
+           
+           // We transition the target core to SIPI state
+           dst_core->core_run_state = CORE_RUNNING;  // note: locking should not be needed here
+
+           // As with INIT, we should not need to do anything else
+
+           PrintDebug("icc_bus: SIPI delivery done\n");
+
+           break;                                                      
+       }
+       case 2: // SMI                  
+       case 3: // reserved                                             
+       case 4: // NMI                                  
+       case 7: // ExtInt
+       default:
+           PrintError("IPI %d delivery is unsupported\n", del_mode); 
+           return -1;
+    }
+
+    return 0;
+
+}
+
+
+static int route_ipi(struct guest_info * core, struct apic_dev_state * apic_dev,
+                    struct apic_state * src_apic,  uint32_t icr_val) {
+    struct int_cmd_reg * icr = (struct int_cmd_reg *)&icr_val;
+    struct apic_state * dest_apic = NULL;
+
+    PrintDebug("icc_bus: icc_bus=%p, src_apic=%u, icr_data=%llx, extirq=%u\n", 
+              icc_bus, src_apic, icr_data, extirq);
+
+
+    // initial sanity checks
+    if (src_apic == NULL) { 
+       PrintError("icc_bus: Apparently sending from unregistered apic id=%d\n", 
+                  src_apic->core->cpu_id);
+       return -1;
+    }
+
+
+    if ((icr->dst_mode == 0) && (icr->dst >= apic_dev->num_apics)) { 
+       PrintError("icc_bus: Attempted send to unregistered apic id=%u\n", 
+                  icr->dst);
+       return -1;
+    }
+
+    dest_apic =  &(apic_dev->apics[icr->dst]);
+
+
+    PrintDebug("icc_bus: IPI %s %u from %s %u to %s %s %u (icr=0x%llx, extirq=%u)\n",
+              deliverymode_str[icr->del_mode], 
+              icr->vec, 
+              (src_apic == state->ioapic_id) ? "ioapic" : "apic",
+              src_apic,               
+              (icr->dst_mode == 0) ? "(physical)" : "(logical)", 
+              shorthand_str[icr->dst_shorthand], 
+              icr->dst,
+              icr->val,
+              extirq);
+
+
+    switch (icr->dst_shorthand) {
+
+       case 0:  // no shorthand
+           if (icr->dst_mode == 0) { 
+               // physical delivery
+
+               if (deliver_ipi(core, src_apic, dest_apic, 
+                               icr->vec, icr->del_mode) == -1) {
+                   PrintError("Error: Could not deliver IPI\n");
+                   return -1;
+               }
+
+           } else {
+               // logical delivery
+               int i;
+               uint8_t mda = icr->dst;
+
+               for (i = 0; i < apic_dev->num_apics; i++) { 
+                    dest_apic = &(apic_dev->apics[i]);
+                    int del_flag = should_deliver_ipi(dest_apic->core, dest_apic, mda);
+                    
+                    if (del_flag == -1) {
+                        PrintError("Error checking delivery mode\n");
+                        return -1;
+                    } else if (del_flag == 1) {
+                       if (deliver_ipi(core, src_apic, dest_apic, 
+                                       icr->vec, icr->del_mode) == -1) {
+                           PrintError("Error: Could not deliver IPI\n");
+                           return -1;
+                       }
+                   }
+               }
+           }
+           
+           break;
+           
+       case 1:  // self
+
+           if (icr->dst_mode == 0) { 
+               if (deliver_ipi(core, src_apic, src_apic, icr->vec, icr->del_mode) == -1) {
+                   PrintError("Could not deliver IPI\n");
+                   return -1;
+               }
+           } else {
+               // logical delivery
+               PrintError("icc_bus: use of logical delivery in self is not yet supported.\n");
+               return -1;
+           }
+           break;
+           
+       case 2: 
+       case 3: { // all and all-but-me
+           // assuming that logical verus physical doesn't matter
+           // although it is odd that both are used
+           int i;
+
+           for (i = 0; i < apic_dev->num_apics; i++) { 
+               dest_apic = &(apic_dev->apics[i]);
+
+               if ((dest_apic != src_apic) || (icr->dst_shorthand == 2)) { 
+                   if (deliver_ipi(core, src_apic, dest_apic, icr->vec, icr->del_mode) == -1) {
+                       PrintError("Error: Could not deliver IPI\n");
+                       return -1;
+                   }
+               }
+           }   
+
+           break;
+       }
+       default:
+           PrintError("Error routing IPI, invalid Mode (%d)\n", icr->dst_shorthand);
+           return -1;
+    }
+    
+
+    return 0;
+}
+
+
+
 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);
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]);
     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;
@@ -745,7 +1033,8 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui
  *
  */
 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);
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); 
     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;
@@ -909,13 +1198,15 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
        case INT_CMD_LO_OFFSET:
            apic->int_cmd.lo = op_val;
 
-           // ICC???
            PrintDebug("apic %u: core %u: sending cmd 0x%llx to apic %u\n", 
                       apic->lapic_id.val, core->cpu_id,
                       apic->int_cmd.val, apic->int_cmd.dst);
-           if (v3_icc_send_ipi(apic->icc_bus, apic->lapic_id.val, apic->int_cmd.val, 0)==-1) { 
+
+           if (route_ipi(core, apic_dev, apic, apic->int_cmd.val) == -1) { 
+               PrintError("IPI Routing failure\n");
                return -1;
            }
+
            break;
 
        case INT_CMD_HI_OFFSET:
@@ -943,8 +1234,9 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
 /* Interrupt Controller Functions */
 
 // returns 1 if an interrupt is pending, 0 otherwise
-static int apic_intr_pending(struct guest_info * info, void * private_data) {
-    struct apic_state * apic = (struct apic_state *)private_data;
+static int apic_intr_pending(struct guest_info * core, void * private_data) {
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); 
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -958,8 +1250,9 @@ static int apic_intr_pending(struct guest_info * info, void * private_data) {
     return 0;
 }
 
-static int apic_get_intr_number(struct guest_info * info, void * private_data) {
-    struct apic_state * apic = (struct apic_state *)private_data;
+static int apic_get_intr_number(struct guest_info * core, void * private_data) {
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); 
     int req_irq = get_highest_irr(apic);
     int svc_irq = get_highest_isr(apic);
 
@@ -973,16 +1266,25 @@ static int apic_get_intr_number(struct guest_info * info, void * private_data) {
 }
 
 
-static int apic_raise_intr(struct guest_info * info, int irq, void * private_data) {
-  struct apic_state * apic = (struct apic_state *)private_data;
+int v3_apic_raise_intr(struct v3_vm_info * vm, struct vm_device * dev, 
+                      uint32_t irq, uint32_t dst) {
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev->private_data);
+    struct apic_state * apic = &(apic_dev->apics[dst]); 
+
+    activate_apic_irq(apic, irq);
 
-  return activate_apic_irq(apic, irq);
+    if (V3_Get_CPU() != dst) {
+       v3_interrupt_cpu(vm, dst, 0);
+    }
+
+    return 0;
 }
 
 
 
-static int apic_begin_irq(struct guest_info * info, void * private_data, int irq) {
-    struct apic_state * apic = (struct apic_state *)private_data;
+static int apic_begin_irq(struct guest_info * core, void * private_data, int irq) {
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); 
     int major_offset = (irq & ~0x00000007) >> 3;
     int minor_offset = irq & 0x00000007;
     uint8_t * req_location = apic->int_req_reg + major_offset;
@@ -1007,10 +1309,12 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
 
 
 /* Timer Functions */
-static void apic_update_time(struct guest_info * info, 
+static void apic_update_time(struct guest_info * core, 
                             uint64_t cpu_cycles, uint64_t cpu_freq, 
                             void * priv_data) {
-    struct apic_state * apic = (struct apic_state *)(priv_data);
+    struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data);
+    struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); 
+
     // The 32 bit GCC runtime is a pile of shit
 #ifdef __V3_64BIT__
     uint64_t tmr_ticks = 0;
@@ -1060,7 +1364,7 @@ static void apic_update_time(struct guest_info * info,
            break;
        default:
            PrintError("apic %u: core %u: Invalid Timer Divider configuration\n",
-                      apic->lapic_id.val, info->cpu_id);
+                      apic->lapic_id.val, core->cpu_id);
            return;
     }
 
@@ -1078,7 +1382,7 @@ static void apic_update_time(struct guest_info * info,
                   apic->lapic_id.val, info->cpu_id,
                   apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
 
-       if (apic_intr_pending(info, priv_data)) {
+       if (apic_intr_pending(core, priv_data)) {
            PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", 
                       apic->lapic_id.val, info->cpu_id, 
                       apic_get_intr_number(info, priv_data));
@@ -1086,7 +1390,7 @@ static void apic_update_time(struct guest_info * info,
 
        if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
            PrintError("apic %u: core %u: Could not raise Timer interrupt\n",
-                      apic->lapic_id.val, info->cpu_id);
+                      apic->lapic_id.val, core->cpu_id);
        }
     
        if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) {
@@ -1132,76 +1436,23 @@ static struct v3_device_ops dev_ops = {
     .stop = NULL,
 };
 
-static int apic_should_deliver_flat(struct guest_info * core, uint8_t mda, void * private_data)
-{
-  struct apic_state * apic = (struct apic_state *)private_data;
 
-  if (mda==0xff ||                         // broadcast or
-      (apic->log_dst.dst_log_id & mda)) {  // I am in the set 
-       PrintDebug("apic %u core %u: accepting flat IRQ (mda 0x%x == log_dst 0x%x)\n",
-                  apic->lapic_id.val, core->cpu_id, mda, apic->log_dst.dst_log_id);
-      return 1;
-  } else {
-       PrintDebug("apic %u core %u: rejecting flat IRQ (mda 0x%x != log_dst 0x%x)\n",
-                  apic->lapic_id.val, core->cpu_id, mda, apic->log_dst.dst_log_id);
-      return 0;
-  }
-}
 
-static int apic_should_deliver_cluster(struct guest_info * core, uint8_t mda, void * private_data)
-{
-  struct apic_state * apic = (struct apic_state *)private_data;
 
-  if (mda==0xff ||                                                 // broadcast or
-      ( ((mda & 0xf0) == (apic->log_dst.dst_log_id & 0xf0)) &&     // (I am in the cluster and
-        ((mda & 0x0f)  & (apic->log_dst.dst_log_id & 0x0f)) ) ) {  //  I am in the set)
-       PrintDebug("apic %u core %u: accepting clustered IRQ (mda 0x%x == log_dst 0x%x)\n",
-                  apic->lapic_id.val, core->cpu_id, mda, apic->log_dst.dst_log_id);
-                  
-      return 1;
-  } else {
-       PrintDebug("apic %u core %u: rejecting clustered IRQ (mda 0x%x != log_dst 0x%x)\n",
-                  apic->lapic_id.val, core->cpu_id, mda, apic->log_dst.dst_log_id);
-      return 0;
-  }
-}
-
-static int apic_should_deliver(struct guest_info * core, uint8_t mda, void *private_data)
-{
-    struct apic_state * apic = (struct apic_state *)private_data;
-    if (apic->dst_fmt.model == 0xf) {
-       return apic_should_deliver_cluster(core, mda, private_data);
-    } else if (apic->dst_fmt.model == 0x0) {
-       return apic_should_deliver_flat(core, mda, private_data);
-    } else {
-       PrintError("apic %u core %u: invalid destination format register value 0x%x for logical mode delivery.\n", apic->lapic_id.val, core->cpu_id, apic->dst_fmt.model);
-       return 0;
-    }
-}
-
-static struct v3_icc_ops icc_ops = {
-    .raise_intr = apic_raise_intr,
-    .should_deliver = apic_should_deliver,
-};
 
 static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-    PrintDebug("apic: creating an APIC for each core\n");
     char * dev_id = v3_cfg_val(cfg, "ID");
-    char * icc_bus_id = v3_cfg_val(cfg, "bus");
-    struct vm_device * icc = v3_find_dev(vm, icc_bus_id);
-    int i;
+    struct apic_dev_state * apic_dev = NULL;
+    int i = 0;
 
-    if (!icc) {
-        PrintError("apic: Cannot find ICC Bus (%s)\n", icc_bus_id);
-        return -1;
-    }
+    PrintDebug("apic: creating an APIC for each core\n");
 
-    // We allocate one apic per core
-    // APICs are accessed via index which correlates with the core's cpu_id 
-    // 0..num_cores-1   at num_cores is the ioapic (one only)
-    struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state) * vm->num_cores);
+    apic_dev = (struct apic_dev_state *)V3_Malloc(sizeof(struct apic_dev_state) + 
+                                                 sizeof(struct apic_state) * vm->num_cores);
 
-    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic);
+    apic_dev->num_apics = vm->num_cores;
+
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic_dev);
 
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("apic: Could not attach device %s\n", dev_id);
@@ -1210,30 +1461,34 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     
     for (i = 0; i < vm->num_cores; i++) {
+       struct apic_state * apic = &(apic_dev->apics[i]);
        struct guest_info * core = &(vm->cores[i]);
 
-       init_apic_state(&(apic[i]),i,icc);
-
-       v3_register_intr_controller(core, &intr_ops, &(apic[i]));
+       apic->core = core;
 
-       v3_add_timer(core, &timer_ops, &(apic[i]));
+       init_apic_state(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_register_intr_controller(core, &intr_ops, apic_dev);
 
-       v3_icc_register_apic(core, icc, i, &icc_ops, &(apic[i]));
+       v3_add_timer(core, &timer_ops, apic_dev);
 
-       PrintDebug("apic %u: (setup device): done, my id is %u\n", i, apic[i].lapic_id.val);
+       v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev);
 
+       PrintDebug("apic %u: (setup device): done, my id is %u\n", i, apic->lapic_id.val);
     }
 
+#ifdef CONFIG_DEBUG_APIC
     for (i = 0; i < vm->num_cores; i++) {
+       struct apic_state * apic = &(apic_dev->apics[i]);
        PrintDebug("apic: sanity check: apic %u (at %p) has id %u and msr value %llx\n",
-                  i, &(apic[i]), apic[i].lapic_id.val, apic[i].base_addr_msr.value);
+                  i, apic, apic->lapic_id.val, apic->base_addr_msr.value);
     }
+#endif
+
 
-    PrintDebug("apic: priv_data is at %p\n", apic);
+    PrintDebug("apic: priv_data is at %p\n", apic_dev);
 
-    v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
+    v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, apic_dev);
 
     return 0;
 }
diff --git a/palacios/src/devices/icc_bus.c b/palacios/src/devices/icc_bus.c
deleted file mode 100644 (file)
index f1cb982..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico.  You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm_dev_mgr.h>
-#include <palacios/vmm_sprintf.h>
-#include <palacios/vm_guest.h>
-#include <devices/icc_bus.h>
-#include <devices/apic_regs.h>
-
-#define MAX_APICS 256
-
-#ifndef CONFIG_DEBUG_ICC_BUS
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif
-
-
-void v3_force_exit(void *p) {
-#ifdef CONFIG_DEBUG_ICC_BUS
-    struct guest_info *core=(struct guest_info *)p;
-#endif
-    PrintDebug("core %u: Forced to exit!\n",core->cpu_id);
-}
-
-struct ipi_thunk_data {
-    struct vm_device * target;
-    uint64_t val;
-};
-
-
-
-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];
-    
-    uint32_t         ioapic_id;
-};
-
-static struct v3_device_ops dev_ops = {
-    .free = NULL,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
-};
-
-#ifdef CONFIG_DEBUG_ICC_BUS
-static char *shorthand_str[] = { 
-    "(no shorthand)",
-    "(self)",
-    "(all)",
-    "(all-but-me)",
- };
-
-static char *deliverymode_str[] = { 
-    "(fixed)",
-    "(lowest priority)",
-    "(SMI)",
-    "(reserved)",
-    "(NMI)",
-    "(INIT)",
-    "(Start Up)",
-    "(ExtInt)",
-};
-#endif
-
-
-static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cmd_reg *icr, struct icc_bus_state * state, uint32_t extirq) {
-
-    switch (icr->del_mode) {                                           
-
-       case 0:  //fixed
-       case 1: // lowest priority
-       case 7: // ExtInt
-           PrintDebug("icc_bus: delivering IRQ to core %u\n",dest_apic->core->cpu_id); 
-
-           dest_apic->ops->raise_intr(dest_apic->core, 
-                                      (icr->del_mode != 7) ? icr->vec : extirq,
-                                      dest_apic->priv_data); 
-
-           if ((src_apic != state->ioapic_id) && (dest_apic->core->cpu_id != src_apic)) { 
-               // Assume core # is same as logical processor for now
-               // TODO FIX THIS FIX THIS
-               // THERE SHOULD BE:  guestapicid->virtualapicid map,
-               //                   cpu_id->logical processor map
-               //     host maitains logical proc->phsysical proc
-               PrintDebug("icc_bus: non-local core, forcing it to exit\n"); 
-
-               V3_Call_On_CPU(dest_apic->core->cpu_id, v3_force_exit, (void *)(dest_apic->core));
-               // TODO: do what the print says
-           }                                                   
-           break;                                                      
-           
-       case 2:   //SMI                 
-           PrintError("icc_bus: SMI delivery is unsupported\n");       
-           return -1;                                          
-           break;                                                      
-           
-       case 3:  //reserved                                             
-           PrintError("icc_bus: Reserved delivery mode 3 is unsupported\n"); 
-           return -1;                                          
-           break;                                                      
-
-       case 4:  //NMI                                  
-           PrintError("icc_bus: NMI delivery is unsupported\n"); 
-           return -1;                                          
-           break;                                                      
-
-       case 5: { //INIT
-           struct guest_info *core = dest_apic->core;
-
-           PrintDebug("icc_bus: INIT delivery to core %u\n", core->cpu_id);
-
-           // TODO: any APIC reset on dest core (shouldn't be needed, but not sure...)
-
-           // Sanity check
-           if (dest_apic->ipi_state != INIT) { 
-               PrintError("icc_bus: Warning: core %u is not in INIT state (mode = %d), ignored\n",
-                          core->cpu_id, core->cpu_mode);
-               // Only a warning, since INIT INIT SIPI is common
-               break;
-           }
-
-           // We transition the target core to SIPI state
-           dest_apic->ipi_state = SIPI;  // note: locking should not be needed here
-
-           // That should be it since the target core should be
-           // waiting in host on this transition
-           // either it's on another core or on a different preemptive thread
-           // in both cases, it will quickly notice this transition 
-           // in particular, we should not need to force an exit here
-
-           PrintDebug("icc_bus: INIT delivery done\n");
-
-       }
-           break;                                                      
-
-       case 6: { //SIPI
-           struct guest_info *core = dest_apic->core;
-
-           // Sanity check
-           if (dest_apic->ipi_state != SIPI) { 
-               PrintError("icc_bus: core %u is not in SIPI state (mode = %d), ignored!\n",core->cpu_id, core->cpu_mode);
-               break;
-           }
-
-           // Write the RIP, CS, and descriptor
-           // assume the rest is already good to go
-           //
-           // vector VV -> rip at 0
-           //              CS = VV00
-           //  This means we start executing at linear address VV000
-           //
-           // So the selector needs to be VV00
-           // and the base needs to be VV000
-           //
-           core->rip = 0;
-           core->segments.cs.selector = icr->vec << 8;
-           core->segments.cs.limit = 0xffff;
-           core->segments.cs.base = icr->vec << 12;
-
-           PrintDebug("icc_bus: SIPI delivery (0x%x -> 0x%x:0x0) to core %u\n",
-                      icr->vec, core->segments.cs.selector, core->cpu_id);
-           // Maybe need to adjust the APIC?
-           
-           // We transition the target core to SIPI state
-           core->core_run_state = CORE_RUNNING;  // note: locking should not be needed here
-
-           // As with INIT, we should not need to do anything else
-
-           PrintDebug("icc_bus: SIPI delivery done\n");
-
-       }
-           break;                                                      
-    }
-
-    return 0;
-} 
-
-
-//
-// icr_data contains interrupt vector *except* for ext_int
-// in which case it is given via irq
-//
-
-int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_data, uint32_t extirq) {
-
-    struct int_cmd_reg *icr = (struct int_cmd_reg *)&icr_data;
-
-    struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data;
-    struct apic_data * dest_apic = NULL;
-    PrintDebug("icc_bus: icc_bus=%p, src_apic=%u, icr_data=%llx, extirq=%u\n", 
-              icc_bus, src_apic, icr_data, extirq);
-
-    // initial sanity checks
-    if ((src_apic >= MAX_APICS) || 
-       ((state->apics[src_apic].present == 0) && 
-        (src_apic != state->ioapic_id))) { 
-       PrintError("icc_bus: Apparently sending from unregistered apic id=%u\n",src_apic);
-       return -1;
-    }
-
-
-    if ((icr->dst_mode == 0) && (state->apics[icr->dst].present == 0)) { 
-       PrintError("icc_bus: Attempted send to unregistered apic id=%u\n", icr->dst);
-       return -1;
-    }
-
-    dest_apic =  &(state->apics[icr->dst]);
-
-
-    PrintDebug("icc_bus: IPI %s %u from %s %u to %s %s %u (icr=0x%llx, extirq=%u)\n",
-              deliverymode_str[icr->del_mode], icr->vec, 
-              src_apic==state->ioapic_id ? "ioapic" : "apic",
-              src_apic,               
-              icr->dst_mode==0 ? "(physical)" : "(logical)", 
-              shorthand_str[icr->dst_shorthand], icr->dst,icr->val,
-              extirq);
-
-    /*
-
-    if (icr->dst==state->ioapic_id) { 
-       PrintError("icc_bus: Attempted send to ioapic ignored\n");
-       return -1;
-    }
-    */
-
-
-
-    switch (icr->dst_shorthand) {
-
-       case 0:  // no shorthand
-
-           if (icr->dst_mode==0) { 
-               // physical delivery
-               struct apic_data * dest_apic =  &(state->apics[icr->dst]);
-               if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                   return -1;
-               }
-           } else {
-               // logical delivery
-               int i;
-               uint8_t mda = icr->dst;
-               for (i=0;i<MAX_APICS;i++) { 
-                   struct apic_data *dest_apic=&(state->apics[i]);
-                   if (dest_apic->present &&
-                       dest_apic->ops->should_deliver(dest_apic->core,
-                                                      mda,
-                                                      dest_apic->priv_data)) {
-                       if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                           return -1;
-                       }
-                   }
-               }
-           }
-           
-           break;
-           
-       case 1:  // self
-
-           if (icr->dst_mode==0) { 
-               // physical delivery
-               if (icr->dst==state->ioapic_id) { 
-                   PrintError("icc_bus: ioapic attempting to send to itself\n");
-                   return -1;
-               }
-               struct apic_data *dest_apic=&(state->apics[src_apic]);
-               if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                   return -1;
-               }
-           } else {
-               // logical delivery
-               PrintError("icc_bus: use of logical delivery in self is not yet supported.\n");
-
-               return -1;
-           }
-           break;
-           
-       case 2: 
-
-       case 3: { // all and all-but-me
-           // assuming that logical verus physical doesn't matter
-           // although it is odd that both are used
-           int i;
-           for (i=0;i<MAX_APICS;i++) { 
-               struct apic_data *dest_apic=&(state->apics[i]);
-               if (dest_apic->present && (i!=src_apic || icr->dst_shorthand==2)) { 
-                   if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                       return -1;
-                   }
-               }
-           }
-       }
-           break;
-
-       default:
-           return -1;
-    }
-    
-
-    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("icc_bus: 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("icc_bus: Registered apic %u\n", apic_num);
-
-    return 0;
-}
-
-
-int v3_icc_register_ioapic(struct v3_vm_info *vm, struct vm_device * icc_bus, uint8_t apic_num)
-{
-    struct icc_bus_state * icc = (struct icc_bus_state *)icc_bus->private_data;
-
-    if (icc->ioapic_id) { 
-       PrintError("icc_bus: Attempt to register a second ioapic!\n");
-       return -1;
-    }
-
-    icc->ioapic_id=apic_num;
-
-    PrintDebug("icc_bus: Registered ioapic %u\n", apic_num);
-    
-
-    return 0;
-}
-
-
-static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-    PrintDebug("icc_bus: Creating ICC_BUS\n");
-
-    char * dev_id = v3_cfg_val(cfg, "ID");
-
-    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(dev_id, &dev_ops, icc_bus);
-
-    if (v3_attach_device(vm, dev) == -1) {
-        PrintError("icc_bus: Could not attach device %s\n", dev_id);
-        return -1;
-    }
-
-    return 0;
-}
-
-
-
-device_register("ICC_BUS", icc_bus_init)
index fc6fdb9..8fa49ee 100644 (file)
@@ -20,8 +20,7 @@
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
-#include <devices/icc_bus.h>
-#include <devices/apic_regs.h>
+#include <devices/apic.h>
 #include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_IO_APIC
@@ -136,7 +135,7 @@ struct io_apic_state {
   
     struct redir_tbl_entry redir_tbl[24];
 
-    struct vm_device * icc_bus;
+    struct vm_device * apic_dev;
   
 };
 
@@ -276,26 +275,19 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq
 
     if (irq_entry->mask == 0) {
 
-       PrintDebug("ioapic %u: IOAPIC Signalling APIC to raise INTR %d\n", ioapic->ioapic_id.id, irq_entry->vec);
+       PrintDebug("ioapic %u: IOAPIC Signalling APIC to raise INTR %d\n", 
+                  ioapic->ioapic_id.id, irq_entry->vec);
 
-
-       // the format of the redirection table entry is just slightly 
-       // different than that of the lapic's cmd register, which is the other
-       // way an IPI is initiated.   So we will translate
-       //
-       struct int_cmd_reg icr;
        
-       icr.val = irq_entry->val;
-       icr.rsvd1=0;
-       icr.lvl=1;
-       icr.trig_mode=irq_entry->trig_mode;
-       icr.rem_rd_status=0;
-       icr.dst_shorthand=0; // no shorthand
-       icr.rsvd2=0;
-
-       PrintDebug("io apic %u: raising irq %u on ICC bus.\n",
-                  ioapic->ioapic_id.id, irq);
-       v3_icc_send_ipi(ioapic->icc_bus, ioapic->ioapic_id.id,icr.val, irq);
+       // May need these for future reference
+       //      icr.val = irq_entry->val;
+       //      icr.trig_mode = irq_entry->trig_mode;
+
+       PrintDebug("io apic: raising irq %u\n", irq);
+
+
+       v3_apic_raise_intr(vm, ioapic->apic_dev, irq, irq_entry->val);
+
     }
 
     return 0;
@@ -331,19 +323,15 @@ static struct v3_device_ops dev_ops = {
 
 
 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, "bus"));
+    struct vm_device * apic_dev = v3_find_dev(vm, v3_cfg_val(cfg, "apic"));
     char * dev_id = v3_cfg_val(cfg, "ID");
 
-    if (!icc_bus) {
-       PrintError("ioapic: Could not locate ICC BUS device (%s)\n", v3_cfg_val(cfg, "bus"));
-       return -1;
-    }
 
     PrintDebug("ioapic: Creating IO APIC\n");
 
     struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state));
 
-    ioapic->icc_bus = icc_bus;
+    ioapic->apic_dev = apic_dev;
 
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ioapic);
 
@@ -358,8 +346,6 @@ static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     init_ioapic_state(ioapic,vm->num_cores);
 
-    v3_icc_register_ioapic(vm,icc_bus,ioapic->ioapic_id.id);
-
     v3_hook_full_mem(vm, V3_MEM_CORE_ANY, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
                     ioapic_read, ioapic_write, dev);