Changeset 49e6c6b4 in mainline for kernel/arch/ia32/src/smp/apic.c


Ignore:
Timestamp:
2012-06-30T23:54:42Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2ee1ccc
Parents:
1f092d9
Message:

ipi: Added support for unicast IPI on amd64, ia32.

File:
1 edited

Legend:

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

    r1f092d9 r49e6c6b4  
    259259}
    260260
     261static void ipi_wait_for_idle(void)
     262{
     263        icr_t icr;
     264       
     265        /* Wait for the destination cpu to accept the previous ipi. */
     266        do {
     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       
     300#ifdef CONFIG_DEBUG
     301        icr.lo = l_apic[ICRlo];
     302        if (icr.delivs == DELIVS_PENDING) {
     303                printf("IPI is pending.\n");
     304        }
     305#endif
     306       
     307        return apic_poll_errors();
     308}
     309
    261310/** Send all CPUs excluding CPU IPI vector.
    262311 *
     
    269318{
    270319        icr_t icr;
     320
     321        /* Wait for a destination cpu to accept our previous ipi. */
     322        ipi_wait_for_idle();
    271323       
    272324        icr.lo = l_apic[ICRlo];
     
    466518        dfr.model = MODEL_FLAT;
    467519        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       
    468530}
    469531
Note: See TracChangeset for help on using the changeset viewer.