X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Ficc_bus.c;h=0a74eee17f37666cdc54ef5855f3a6ddc10b918f;hb=27eb2f39dd8e616c48f115c67ecca22f1c799b23;hp=3606be1ff9ed5498cad12ffeb1eca88e413c4779;hpb=941622f53f723161738e9f9889f5360af1bc9c40;p=palacios.git diff --git a/palacios/src/devices/icc_bus.c b/palacios/src/devices/icc_bus.c index 3606be1..0a74eee 100644 --- a/palacios/src/devices/icc_bus.c +++ b/palacios/src/devices/icc_bus.c @@ -134,14 +134,14 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm // TODO: any APIC reset on dest core (shouldn't be needed, but not sure...) // Sanity check - if (core->cpu_mode!=INIT) { + if (core->cpu_mode != INIT) { PrintError("icc_bus: Warning: core %u is not in INIT state, ignored\n",core->cpu_id); // Only a warning, since INIT INIT SIPI is common break; } // We transition the target core to SIPI state - core->cpu_mode=SIPI; // note: locking should not be needed here + core->cpu_mode = SIPI; // note: locking should not be needed here // That should be it since the target core should be // waiting in host on this transition @@ -173,17 +173,17 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm // 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; + 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->cpu_mode=REAL; // note: locking should not be needed here + core->cpu_mode = REAL; // note: locking should not be needed here // As with INIT, we should not need to do anything else @@ -201,6 +201,7 @@ 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 dfr_data, uint32_t extirq) { @@ -208,18 +209,29 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_ 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; + 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 && src_apic!=state->ioapic_id)) { + 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) { - PrintError("icc_bus: Attempted send to unregistered apic id=%u\n",icr->dst); + + + 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, dfr=0x%x) (extirq=%u)\n", deliverymode_str[icr->del_mode], icr->vec, src_apic==state->ioapic_id ? "ioapic" : "apic", @@ -241,6 +253,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 (icr->dst_mode==0) { // physical delivery struct apic_data * dest_apic = &(state->apics[icr->dst]); @@ -311,11 +324,13 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_ PrintError("icc_bus: unknown logical delivery model 0x%x\n", dfr->model); return -1; } + } break; case 1: // self + if (icr->dst_mode==0) { // physical delivery if (icr->dst==state->ioapic_id) { @@ -329,31 +344,32 @@ int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t src_apic, uint64_t icr_ } 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 - if (icr->dst_mode==0) { - // physical - int i; - for (i=0;iapics[i]); - if (dest_apic->present && (i!=src_apic || icr->dst_shorthand==2)) { - if (deliver(src_apic,dest_apic,icr,state,extirq)) { - return -1; - } + + 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;iapics[i]); + if (dest_apic->present && (i!=src_apic || icr->dst_shorthand==2)) { + if (deliver(src_apic,dest_apic,icr,state,extirq)) { + return -1; } } - } else { - // logical delivery - PrintError("icc_bus: use of logical delivery in %s is not yet supported\n", - icr->dst_shorthand==2 ? "all" : "all-but-me" ); - return -1; } + } break; + + default: + return -1; } + return 0; } @@ -404,15 +420,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; }