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
[palacios.git] / palacios / src / devices / icc_bus.c
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;
 }