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 destination format (i.e. clustered logical vs. flat logical)
Patrick G. Bridges [Thu, 14 Oct 2010 19:52:14 +0000 (13:52 -0600)]
information from the io_apic since it doesn't know that. The hardware
spec requires that the guest program all apics on the ICC bus into consistent
format mode, either all clustered or all flat, and the irq routing destination
in the io-apic consistently with that, but the io-apic doesn't actually know
if the destination is flat or clustered.

palacios/include/devices/icc_bus.h
palacios/src/devices/apic.c
palacios/src/devices/icc_bus.c
palacios/src/devices/io_apic.c

index 4084340..e9aebbd 100644 (file)
@@ -23,8 +23,7 @@
 
 struct v3_icc_ops {
     int (*raise_intr)(struct guest_info * core, int intr_num, void * private_data);
-    int (*should_deliver_flat)(struct guest_info * core, uint8_t mda, void * private_data);
-    int (*should_deliver_cluster)(struct guest_info * core, uint8_t mda, void * private_data);
+    int (*should_deliver)(struct guest_info * core, uint8_t mda, void * private_data);
 };
 
 
@@ -44,7 +43,7 @@ int v3_icc_register_ioapic(struct v3_vm_info *vm, struct vm_device * icc_bus, ui
  * @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 dfr, uint32_t ext_irq);
+int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t apic_src, uint64_t icr, uint32_t ext_irq);
 
 
 #if 0
index b32e6f8..a844c6c 100644 (file)
@@ -906,7 +906,7 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
            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,apic->dst_fmt.val,0)==-1) { 
+           if (v3_icc_send_ipi(apic->icc_bus, apic->lapic_id.val, apic->int_cmd.val,0)==-1) { 
                return -1;
            }
            break;
@@ -1125,8 +1125,6 @@ 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;
@@ -1161,14 +1159,24 @@ static int apic_should_deliver_cluster(struct guest_info * core, uint8_t mda, vo
   }
 }
 
+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_flat = apic_should_deliver_flat,
-    .should_deliver_cluster = apic_should_deliver_cluster,
+    .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");
index 0a74eee..79f9159 100644 (file)
@@ -202,13 +202,11 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
 // 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 dfr_data, uint32_t extirq) {
+int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_data, uint32_t extirq) {
 
     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 dst_fmt_reg *dfr = (struct dst_fmt_reg*)&dfr_data;
 
     struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data;
     struct apic_data * dest_apic = NULL;
@@ -232,12 +230,12 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
     dest_apic =  &(state->apics[icr->dst]);
 
 
-    PrintDebug("icc_bus: IPI %s %u from %s %u to %s %s %u (icr=0x%llx, dfr=0x%x) (extirq=%u)\n",
+    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, dfr->val,
+              shorthand_str[icr->dst_shorthand], icr->dst,icr->val,
               extirq);
 
     /*
@@ -262,69 +260,19 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_
                }
            } else {
                // logical delivery
-               uint8_t mda = icr->dst; // message destination address, not physical address
-               
-               if (dfr->model==0xf) { 
-                   // flat model
-                   // this means we deliver the IPI each destination APIC where
-                   // mda of sender & ldr of receiver is nonzero
-                   // mda=0xff means broadcast to all
-                   //
-                   int i;
-                   for (i=0;i<MAX_APICS;i++) { 
-                       struct apic_data *dest_apic=&(state->apics[i]);
-                       if (dest_apic->present &&
-                           dest_apic->ops->should_deliver_flat(dest_apic->core,
-                                                               mda,
-                                                               dest_apic->priv_data)) {
-                           if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                               return -1;
-                           }
+               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;
                        }
                    }
-               } else if (dfr->model==0x0) {
-                   // cluster model
-                   //
-                   // there are two variants of this
-                   //
-                   // 1. (ancient P5/P6) All apics are on one bus
-                   //    mda[31:28] is the target cluster, 
-                   //    mda[27:24] has one bit for each apic in the cluster
-                   //    mda[31:28] of sending apic == ldr[31:28] of dest apic means
-                   //      the dest apic is part of the cluster
-                   //      then mda[27:24] & ldr[27:24] nonzero means to deliver
-                   //    also, mda=0xff still means broadcast 
-                   //    So, basically, you have 15 clusters of 4 apics each + broadcast
-                   //
-                   // 2. (current) hierarchical cluster model
-                   //    This is some hwat unclearly documented in volume 3, 9-32
-                   //    basically, you have a hierarchy of clusters that where
-                   //    each cluster has 4 agents (APICs?) and a cluster manager.
-                   //    The cluster manager is not an apic, though, and outside of
-                   //    scope of documents.  Again, you have 15 clusters of 4 apics
-                   //    each + broadcast.   My impression is that this is identical 
-                   //    to variant 1 for our purposes. 
-                   //
-                   //
-                   // if we are in lowest priorty mode, we should just pick one
-                   // according to the arbitrarion prioty register
-                   int i;
-                   for (i=0;i<MAX_APICS;i++) { 
-                       struct apic_data *dest_apic=&(state->apics[i]);
-                       if (dest_apic->present &&
-                           dest_apic->ops->should_deliver_cluster(dest_apic->core,
-                                                                  mda,
-                                                                  dest_apic->priv_data)) {
-                           if (deliver(src_apic,dest_apic,icr,state,extirq)) { 
-                               return -1;
-                           }
-                       }
-                   }
-               } else {
-                   PrintError("icc_bus: unknown logical delivery model 0x%x\n", dfr->model);
-                   return -1;
                }
-
            }
            
            break;
index 48f1ed6..fc6fdb9 100644 (file)
@@ -293,11 +293,9 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq
        icr.dst_shorthand=0; // no shorthand
        icr.rsvd2=0;
 
-       // Note: 0 yhere is "cluster model", but it should be irrelevant
-       // since we are sending this as a physical destination
        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, 0, irq);
+       v3_icc_send_ipi(ioapic->icc_bus, ioapic->ioapic_id.id,icr.val, irq);
     }
 
     return 0;