Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/smp/apic.c

    r5e4f22b r49e6c6b4  
    259259}
    260260
    261 #define DELIVS_PENDING_SILENT_RETRIES   4       
    262 
    263 static void l_apic_wait_for_delivery(void)
     261static void ipi_wait_for_idle(void)
    264262{
    265263        icr_t icr;
    266         unsigned retries = 0;
    267 
     264       
     265        /* Wait for the destination cpu to accept the previous ipi. */
    268266        do {
    269                 if (retries++ > DELIVS_PENDING_SILENT_RETRIES) {
    270                         retries = 0;
     267                icr.lo = l_apic[ICRlo];
     268        } while (icr.delivs != DELIVS_IDLE);
     269}
     270
     271/** Send one CPU an IPI vector.
     272 *
     273 * @param apicid Physical APIC ID of the destination CPU.
     274 * @param vector Interrupt vector to be sent.
     275 *
     276 * @return 0 on failure, 1 on success.
     277 */
     278int l_apic_send_custom_ipi(uint8_t apicid, uint8_t vector)
     279{
     280        icr_t icr;
     281
     282        /* Wait for a destination cpu to accept our previous ipi. */
     283        ipi_wait_for_idle();
     284       
     285        icr.lo = l_apic[ICRlo];
     286        icr.hi = l_apic[ICRhi];
     287       
     288        icr.delmod = DELMOD_FIXED;
     289        icr.destmod = DESTMOD_PHYS;
     290        icr.level = LEVEL_ASSERT;
     291        icr.shorthand = SHORTHAND_NONE;
     292        icr.trigger_mode = TRIGMOD_LEVEL;
     293        icr.vector = vector;
     294        icr.dest = apicid;
     295
     296        /* Send the IPI by writing to l_apic[ICRlo]. */
     297        l_apic[ICRhi] = icr.hi;
     298        l_apic[ICRlo] = icr.lo;
     299       
    271300#ifdef CONFIG_DEBUG
    272                         printf("IPI is pending.\n");
     301        icr.lo = l_apic[ICRlo];
     302        if (icr.delivs == DELIVS_PENDING) {
     303                printf("IPI is pending.\n");
     304        }
    273305#endif
    274                         delay(20);
    275                 }
    276                 icr.lo = l_apic[ICRlo];
    277         } while (icr.delivs == DELIVS_PENDING);
    278        
     306       
     307        return apic_poll_errors();
    279308}
    280309
     
    289318{
    290319        icr_t icr;
     320
     321        /* Wait for a destination cpu to accept our previous ipi. */
     322        ipi_wait_for_idle();
    291323       
    292324        icr.lo = l_apic[ICRlo];
     
    299331       
    300332        l_apic[ICRlo] = icr.lo;
    301 
    302         l_apic_wait_for_delivery();
     333       
     334        icr.lo = l_apic[ICRlo];
     335        if (icr.delivs == DELIVS_PENDING) {
     336#ifdef CONFIG_DEBUG
     337                printf("IPI is pending.\n");
     338#endif
     339        }
    303340       
    304341        return apic_poll_errors();
     
    342379                return 0;
    343380       
    344         l_apic_wait_for_delivery();
    345 
    346381        icr.lo = l_apic[ICRlo];
     382        if (icr.delivs == DELIVS_PENDING) {
     383#ifdef CONFIG_DEBUG
     384                printf("IPI is pending.\n");
     385#endif
     386        }
     387       
    347388        icr.delmod = DELMOD_INIT;
    348389        icr.destmod = DESTMOD_PHYS;
     
    477518        dfr.model = MODEL_FLAT;
    478519        l_apic[DFR] = dfr.value;
     520       
     521        if (CPU->arch.id != l_apic_id()) {
     522#ifdef CONFIG_DEBUG
     523                printf("lapic error: LAPIC ID (%" PRIu8 ") and hw ID assigned by BSP"
     524                        " (%u) differ. Correcting to LAPIC ID.\n", l_apic_id(),
     525                        CPU->arch.id);
     526#endif
     527                CPU->arch.id = l_apic_id();
     528        }
     529       
    479530}
    480531
Note: See TracChangeset for help on using the changeset viewer.