X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fapic.c;h=7f2eb45d16d7d3cc0d3e7999bf64a27d820d8e8f;hb=8ca1d3b4d7a7266a92ef99afeee99097da838ae8;hp=ca991a303a173af40d6ed0a19c7b1ff7d82d3c03;hpb=bba68c448a941e0beb562f670f1a5901e5d07a54;p=palacios.git diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index ca991a3..7f2eb45 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -28,17 +28,13 @@ #include -// -// MUST DO APIC SCAN FOR PHYSICAL DELIVERY -// - -#ifndef CONFIG_DEBUG_APIC +#ifndef V3_CONFIG_DEBUG_APIC #undef PrintDebug #define PrintDebug(fmt, args...) - #else + static char * shorthand_str[] = { "(no shorthand)", "(self)", @@ -59,7 +55,6 @@ static char * deliverymode_str[] = { #endif - typedef enum { APIC_TMR_INT, APIC_THERM_INT, APIC_PERF_INT, APIC_LINT0_INT, APIC_LINT1_INT, APIC_ERR_INT } apic_irq_type_t; @@ -460,7 +455,7 @@ static int apic_do_eoi(struct apic_state * apic) { *svc_location &= ~flag; -#ifdef CONFIG_CRAY_XT +#ifdef V3_CONFIG_CRAY_XT if ((isr_irq == 238) || (isr_irq == 239)) { @@ -644,7 +639,7 @@ static int deliver_ipi(struct apic_state * src_apic, // host maitains logical proc->phsysical proc PrintDebug(" non-local core with new interrupt, forcing it to exit now\n"); -#ifdef CONFIG_MULTITHREAD_OS +#ifdef V3_CONFIG_MULTITHREAD_OS v3_interrupt_cpu(dst_core->vm_info, dst_core->cpu_id, 0); #else V3_ASSERT(0); @@ -711,11 +706,11 @@ static int deliver_ipi(struct apic_state * src_apic, // We transition the target core to SIPI state dst_core->core_run_state = CORE_RUNNING; // note: locking should not be needed here dst_apic->ipi_state = STARTED; - + // As with INIT, we should not need to do anything else - + PrintDebug(" SIPI delivery done\n"); - + break; } case APIC_SMI_DELIVERY: @@ -726,8 +721,29 @@ static int deliver_ipi(struct apic_state * src_apic, PrintError("IPI %d delivery is unsupported\n", del_mode); return -1; } - + return 0; + +} + +static struct apic_state * find_physical_apic(struct apic_dev_state *apic_dev, struct int_cmd_reg *icr) +{ + int i; + + if (icr->dst >0 && icr->dst < apic_dev->num_apics) { + // see if it simply is the core id + if (apic_dev->apics[icr->dst].lapic_id.val == icr->dst) { + return &(apic_dev->apics[icr->dst]); + } + } + + for (i=0;inum_apics;i++) { + if (apic_dev->apics[i].lapic_id.val == icr->dst) { + return &(apic_dev->apics[i]); + } + } + + return NULL; } @@ -747,28 +763,29 @@ static int route_ipi(struct apic_dev_state * apic_dev, icr->dst, icr->val); + switch (icr->dst_shorthand) { case APIC_SHORTHAND_NONE: // no shorthand if (icr->dst_mode == APIC_DEST_PHYSICAL) { - if (icr->dst >= apic_dev->num_apics) { + dest_apic=find_physical_apic(apic_dev,icr); + + if (dest_apic==NULL) { PrintError("apic: Attempted send to unregistered apic id=%u\n", icr->dst); return -1; } - dest_apic = &(apic_dev->apics[icr->dst]); - - V3_Print("apic: phsyical destination of %u (apic %u at 0x%p)\n", icr->dst,dest_apic->lapic_id.val,dest_apic); - if (deliver_ipi(src_apic, dest_apic, icr->vec, icr->del_mode) == -1) { PrintError("apic: Could not deliver IPI\n"); return -1; } + V3_Print("apic: done\n"); + } else if (icr->dst_mode == APIC_DEST_LOGICAL) { if (icr->del_mode!=APIC_LOWEST_DELIVERY ) { @@ -1219,8 +1236,8 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u // Data registers case APIC_ID_OFFSET: - V3_Print("apic %u: core %u: my id is being changed to %u\n", - apic->lapic_id.val, core->cpu_id, op_val); + //V3_Print("apic %u: core %u: my id is being changed to %u\n", + // apic->lapic_id.val, core->cpu_id, op_val); apic->lapic_id.val = op_val; break; @@ -1434,7 +1451,7 @@ int v3_apic_raise_intr(struct v3_vm_info * vm, uint32_t irq, uint32_t dst, void } if (do_xcall > 0 && (V3_Get_CPU() != dst)) { -#ifdef CONFIG_MULTITHREAD_OS +#ifdef V3_CONFIG_MULTITHREAD_OS v3_interrupt_cpu(vm, dst, 0); #else V3_ASSERT(0); @@ -1661,7 +1678,7 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("apic %u: (setup device): done, my id is %u\n", i, apic->lapic_id.val); } -#ifdef CONFIG_DEBUG_APIC +#ifdef V3_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 and core at %p\n",