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.


mark APIC/IO-APIC/ICC bus as experimental features and removed them from the default...
[palacios-OLD.git] / palacios / src / devices / icc_bus.c
index 7f71956..a1ade14 100644 (file)
@@ -84,19 +84,22 @@ static char *deliverymode_str[] = {
     "(NMI)",
     "(INIT)",
     "(Start Up)",
-    "(reserved)",
+    "(ExtInt)",
 };
 #endif
 
 
-static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cmd_reg *icr, struct icc_bus_state * state) {
+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->vec, dest_apic->priv_data); 
+           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
@@ -115,7 +118,6 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
            break;                                                      
            
        case 3:  //reserved                                             
-       case 7:
            PrintError("icc_bus: Reserved delivery mode 3 is unsupported\n"); 
            return -1;                                          
            break;                                                      
@@ -155,10 +157,6 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
 
        case 6: { //SIPI
            struct guest_info *core = dest_apic->core;
-           uint64_t rip = icr->vec << 12;  // vector encodes target address;
-
-           PrintDebug("icc_bus: SIPI delivery (0x%x -> rip=0x%p) to core %u\n",
-                      icr->vec, (void*)rip, core->cpu_id);
 
            // Sanity check
            if (core->cpu_mode!=SIPI) { 
@@ -168,11 +166,21 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
 
            // Write the RIP, CS, and descriptor
            // assume the rest is already good to go
-           core->rip=rip & 0xffff;
-           core->segments.cs.selector = (rip >> 4) & 0xf000;
+           //
+           // 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 = rip & 0xf0000;
+           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
@@ -190,10 +198,13 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
 } 
 
 
+//
+// 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) {
 
-int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_data) {
-
-    PrintDebug("icc_bus: icc_bus=%p, src_apic=%u, icr_data=%llx\n",icc_bus,src_apic,icr_data);
+    PrintDebug("icc_bus: icc_bus=%p, src_apic=%u, icr_data=%llx, extirq=%u\n",icc_bus,src_apic,icr_data,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;
@@ -210,10 +221,10 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
     
     struct apic_data * dest_apic =  &(state->apics[icr->dst]);
 
-
-    PrintDebug("icc_bus: IPI %s %u from %s %u to %s %u (icr=0x%llx)\n",
+    PrintDebug("icc_bus: IPI %s %u from %s %u to %s %u (icr=0x%llx) (extirq=%u)\n",
               deliverymode_str[icr->del_mode], icr->vec, src_apic==state->ioapic_id ? "ioapic" : "apic",
-              src_apic, shorthand_str[icr->dst_shorthand], icr->dst,icr->val);
+              src_apic, shorthand_str[icr->dst_shorthand], icr->dst,icr->val,
+              extirq);
 
 
 
@@ -221,7 +232,7 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
     switch (icr->dst_shorthand) {
 
        case 0:  // no shorthand
-           if (deliver(src_apic,dest_apic,icr,state)) { 
+           if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
                return -1;
            }
            break;
@@ -231,7 +242,7 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
                PrintError("icc_bus: ioapic attempting to send to itself\n");
                return -1;
            }
-           if (deliver(src_apic,dest_apic,icr,state)) { 
+           if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
                return -1;
            }
            break;
@@ -242,7 +253,7 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
            for (i=0;i<MAX_APICS;i++) { 
                dest_apic=&(state->apics[i]);
                if (dest_apic->present && (i!=src_apic || icr->dst_shorthand==2)) { 
-                   if (deliver(src_apic,dest_apic,icr,state)) { 
+                   if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
                        return -1;
                    }
                }
@@ -301,15 +312,15 @@ int v3_icc_register_ioapic(struct v3_vm_info *vm, struct vm_device * icc_bus, ui
 static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("icc_bus: Creating ICC_BUS\n");
 
-    char * name = v3_cfg_val(cfg, "name");
+    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(name, &dev_ops, icc_bus);
+    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", name);
+        PrintError("icc_bus: Could not attach device %s\n", dev_id);
         return -1;
     }