Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 49e6c6b4 in mainline


Ignore:
Timestamp:
2012-06-30T23:54:42Z (8 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
master
Children:
2ee1ccc
Parents:
1f092d9
Message:

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

Location:
kernel
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/cpu.h

    r1f092d9 r49e6c6b4  
    7373        tss_t *tss;
    7474       
     75        unsigned int id; /** CPU's local, ie physical, APIC ID. */
     76       
    7577        size_t iomapver_copy;  /** Copy of TASK's I/O Permission bitmap generation count. */
    7678} cpu_arch_t;
  • kernel/arch/amd64/src/amd64.c

    r1f092d9 r49e6c6b4  
    171171}
    172172
    173 void arch_post_cpu_init()
     173void arch_post_cpu_init(void)
    174174{
    175175#ifdef CONFIG_SMP
  • kernel/arch/amd64/src/cpu/cpu.c

    r1f092d9 r49e6c6b4  
    158158void cpu_print_report(cpu_t* m)
    159159{
    160         printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
     160        printf("cpu%d: (%s family=%d model=%d stepping=%d apicid=%u) %dMHz\n",
    161161            m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model,
    162             m->arch.stepping, m->frequency_mhz);
     162            m->arch.stepping, m->arch.id, m->frequency_mhz);
    163163}
    164164
  • kernel/arch/ia32/include/cpu.h

    r1f092d9 r49e6c6b4  
    6060        unsigned int stepping;
    6161        cpuid_feature_info fi;
     62       
     63        unsigned int id; /** CPU's local, ie physical, APIC ID. */
    6264
    6365        tss_t *tss;
  • kernel/arch/ia32/include/smp/apic.h

    r1f092d9 r49e6c6b4  
    353353extern void l_apic_init(void);
    354354extern void l_apic_eoi(void);
     355extern int l_apic_send_custom_ipi(uint8_t, uint8_t);
    355356extern int l_apic_broadcast_custom_ipi(uint8_t);
    356357extern int l_apic_send_init_ipi(uint8_t);
  • kernel/arch/ia32/src/cpu/cpu.c

    r1f092d9 r49e6c6b4  
    160160void cpu_print_report(cpu_t* cpu)
    161161{
    162         printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n",
    163                 cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,
    164                 cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz);
     162        printf("cpu%u: (%s family=%u model=%u stepping=%u apicid=%u) %" PRIu16
     163                " MHz\n", cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,
     164                cpu->arch.model, cpu->arch.stepping, cpu->arch.id, cpu->frequency_mhz);
    165165}
    166166
  • kernel/arch/ia32/src/ia32.c

    r1f092d9 r49e6c6b4  
    125125}
    126126
    127 void arch_post_cpu_init()
     127void arch_post_cpu_init(void)
    128128{
    129129#ifdef CONFIG_SMP
  • 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
  • kernel/arch/ia32/src/smp/smp.c

    r1f092d9 r49e6c6b4  
    5555#include <memstr.h>
    5656#include <arch/drivers/i8259.h>
     57#include <cpu.h>
    5758
    5859#ifdef CONFIG_SMP
     
    7778                io_apic = (uint32_t *) km_map((uintptr_t) io_apic, PAGE_SIZE,
    7879                    PAGE_WRITE | PAGE_NOT_CACHEABLE);
     80        }
     81}
     82
     83static void cpu_arch_id_init(void)
     84{
     85        ASSERT(ops != NULL);
     86        ASSERT(cpus != NULL);
     87       
     88        for (unsigned int i = 0; i < config.cpu_count; ++i) {
     89                cpus[i].arch.id = ops->cpu_apic_id(i);
    7990        }
    8091}
     
    92103       
    93104        ASSERT(ops != NULL);
     105
     106        /*
     107         * SMP initialized, cpus array allocated. Assign each CPU its
     108         * physical APIC ID.
     109         */
     110        cpu_arch_id_init();
    94111       
    95112        /*
  • kernel/generic/src/main/main.c

    r1f092d9 r49e6c6b4  
    244244       
    245245        cpu_init();
    246        
    247246        calibrate_delay_loop();
     247        arch_post_cpu_init();
     248
    248249        clock_counter_init();
    249250        timeout_init();
Note: See TracChangeset for help on using the changeset viewer.