Index: i386/apic_vector.s =================================================================== RCS file: /cvsroot/src/sys/i386/i386/apic_vector.s,v retrieving revision 1.101 diff -u -r1.101 apic_vector.s --- i386/apic_vector.s 26 May 2004 07:43:41 -0000 1.101 +++ i386/apic_vector.s 15 Nov 2004 02:09:05 -0000 @@ -119,138 +119,11 @@ /* * Global address space TLB shootdown. */ - .text - SUPERALIGN_TEXT -IDTVEC(invltlb) - pushl %eax - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#ifdef COUNT_XINVLTLB_HITS - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs - incl xhits_gbl(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ - - movl %cr3, %eax /* invalidate the TLB */ - movl %eax, %cr3 - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - - lock - incl smp_tlb_wait - - popl %ds - popl %eax - iret -/* - * Single page TLB shootdown - */ .text SUPERALIGN_TEXT -IDTVEC(invlpg) - pushl %eax - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#ifdef COUNT_XINVLTLB_HITS - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs - incl xhits_pg(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ - - movl smp_tlb_addr1, %eax - invlpg (%eax) /* invalidate single page */ - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - - lock - incl smp_tlb_wait - - popl %ds - popl %eax - iret - -/* - * Page range TLB shootdown. - */ - .text - SUPERALIGN_TEXT -IDTVEC(invlrng) - pushl %eax - pushl %edx - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#ifdef COUNT_XINVLTLB_HITS - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs - incl xhits_rng(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ - - movl smp_tlb_addr1, %edx - movl smp_tlb_addr2, %eax -1: invlpg (%edx) /* invalidate single page */ - addl $PAGE_SIZE, %edx - cmpl %eax, %edx - jb 1b - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - - lock - incl smp_tlb_wait - - popl %ds - popl %edx - popl %eax - iret - -/* - * Forward hardclock to another CPU. Pushes a clockframe and calls - * forwarded_hardclock(). - */ - .text - SUPERALIGN_TEXT -IDTVEC(hardclock) - PUSH_FRAME - movl $KDSEL, %eax /* reload with kernel's data segment */ - movl %eax, %ds - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs - - movl lapic, %edx - movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */ - - pushl $0 /* XXX convert trapframe to clockframe */ - call forwarded_hardclock - addl $4, %esp /* XXX convert clockframe to trapframe */ - MEXITCOUNT - jmp doreti - -/* - * Forward statclock to another CPU. Pushes a clockframe and calls - * forwarded_statclock(). - */ - .text - SUPERALIGN_TEXT -IDTVEC(statclock) +IDTVEC(ipi_intr_handler) + PUSH_FRAME movl $KDSEL, %eax /* reload with kernel's data segment */ movl %eax, %ds @@ -260,40 +133,16 @@ movl lapic, %edx movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */ - + FAKE_MCOUNT(TF_EIP(%esp)) pushl $0 /* XXX convert trapframe to clockframe */ - call forwarded_statclock + call ipi_handler addl $4, %esp /* XXX convert clockframe to trapframe */ MEXITCOUNT jmp doreti -/* - * Executed by a CPU when it receives an Xcpuast IPI from another CPU, - * - * The other CPU has already executed aston() or need_resched() on our - * current process, so we simply need to ack the interrupt and return - * via doreti to run ast(). - */ - - .text - SUPERALIGN_TEXT -IDTVEC(cpuast) - PUSH_FRAME - movl $KDSEL, %eax - movl %eax, %ds /* use KERNEL data segment */ - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs - - movl lapic, %edx - movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */ - - FAKE_MCOUNT(TF_EIP(%esp)) - - MEXITCOUNT - jmp doreti + /* * Executed by a CPU when it receives an Xcpustop IPI from another CPU, @@ -363,45 +212,4 @@ popl %ebp iret -/* - * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. - * - * - Calls the generic rendezvous action function. - */ - .text - SUPERALIGN_TEXT -IDTVEC(rendezvous) - PUSH_FRAME - movl $KDSEL, %eax - movl %eax, %ds /* use KERNEL data segment */ - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs - - call smp_rendezvous_action - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - POP_FRAME - iret - -/* - * Clean up when we lose out on the lazy context switch optimization. - * ie: when we are about to release a PTD but a cpu is still borrowing it. - */ - SUPERALIGN_TEXT -IDTVEC(lazypmap) - PUSH_FRAME - movl $KDSEL, %eax - movl %eax, %ds /* use KERNEL data segment */ - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs - - call pmap_lazyfix_action - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - POP_FRAME - iret #endif /* SMP */ Index: i386/intr_machdep.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/intr_machdep.c,v retrieving revision 1.11 diff -u -r1.11 intr_machdep.c --- i386/intr_machdep.c 3 Nov 2004 18:03:06 -0000 1.11 +++ i386/intr_machdep.c 11 Nov 2004 22:31:19 -0000 @@ -205,7 +205,9 @@ isrc->is_pic->pic_eoi_source(isrc); error = 0; /* XXX */ +#if 0 td->td_pflags &= ~TDP_OWEPREEMPT; +#endif critical_exit(); } else { /* Index: i386/local_apic.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/local_apic.c,v retrieving revision 1.9 diff -u -r1.9 local_apic.c --- i386/local_apic.c 14 Jul 2004 18:12:15 -0000 1.9 +++ i386/local_apic.c 12 Nov 2004 04:15:37 -0000 @@ -693,6 +693,62 @@ intr_restore(eflags); } + +static void +lapic_ipi_wait_and_raw(int delay,register_t icrlo, u_int dest) +{ + int x, incr,idle; + register_t value, eflags; + + +/* XXX: Need more sanity checking of icrlo? */ + KASSERT(lapic != NULL, ("%s called too early", __func__)); + KASSERT((dest & ~(APIC_ID_MASK >> APIC_ID_SHIFT)) == 0, + ("%s: invalid dest field", __func__)); + KASSERT((icrlo & APIC_ICRLO_RESV_MASK) == 0, + ("%s: reserved bits set in ICR LO register", __func__)); + + if (delay == -1) { + incr = 0; + delay = 1; + } else + incr = 1; + + /* Set destination in ICR HI register if it is being used. */ + eflags = intr_disable(); + + idle = 0; + + for (x = 0; x < delay; x += incr) { + if ((lapic->icr_lo & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) + { + idle = 1; + break; + } + intr_restore(eflags); + ia32_pause(); + eflags = intr_disable(); + + } + + if (!idle) panic("APIC: Previous IPI is stuck"); + + if ((icrlo & APIC_DEST_MASK) == APIC_DEST_DESTFLD) { + value = lapic->icr_hi; + value &= ~APIC_ID_MASK; + value |= dest << APIC_ID_SHIFT; + lapic->icr_hi = value; + } + + /* Program the contents of the IPI and dispatch it. */ + value = lapic->icr_lo; + value &= APIC_ICRLO_RESV_MASK; + value |= icrlo; + lapic->icr_lo = value; + intr_restore(eflags); +} + + #define BEFORE_SPIN 1000000 #ifdef DETECT_DEADLOCK #define AFTER_SPIN 1000 @@ -725,11 +781,8 @@ destfield = dest; } - /* Wait for an earlier IPI to finish. */ - if (!lapic_ipi_wait(BEFORE_SPIN)) - panic("APIC: Previous IPI is stuck"); - - lapic_ipi_raw(icrlo, destfield); + + lapic_ipi_wait_and_raw(BEFORE_SPIN,icrlo, destfield); #ifdef DETECT_DEADLOCK /* Wait for IPI to be delivered. */ Index: i386/mp_machdep.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.240 diff -u -r1.240 mp_machdep.c --- i386/mp_machdep.c 1 Nov 2004 22:11:27 -0000 1.240 +++ i386/mp_machdep.c 15 Nov 2004 18:25:34 -0000 @@ -201,6 +201,9 @@ } static cpu_info[MAXCPU]; static int cpu_apic_ids[MAXCPU]; + +static volatile u_int cpu_ipi_pending[MAXCPU]; + static u_int boot_address; static void set_logical_apic_ids(void); @@ -212,6 +215,8 @@ static int hlt_logical_cpus; static struct sysctl_ctx_list logical_cpu_clist; + + static void mem_range_AP_init(void) { @@ -349,43 +354,20 @@ POSTCODE(MP_START_POST); - /* Initialize the logical ID to APIC ID table. */ - for (i = 0; i < MAXCPU; i++) + /* Initialize the logical ID to APIC ID table and the IPI pending bitmaps. */ + for (i = 0; i < MAXCPU; i++) { cpu_apic_ids[i] = -1; - - /* Install an inter-CPU IPI for TLB invalidation */ - setidt(IPI_INVLTLB, IDTVEC(invltlb), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - setidt(IPI_INVLPG, IDTVEC(invlpg), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - setidt(IPI_INVLRNG, IDTVEC(invlrng), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - - /* Install an inter-CPU IPI for forwarding hardclock() */ - setidt(IPI_HARDCLOCK, IDTVEC(hardclock), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - - /* Install an inter-CPU IPI for forwarding statclock() */ - setidt(IPI_STATCLOCK, IDTVEC(statclock), + cpu_ipi_pending[i] = 0; + } + + /* Install generic inter-CPU IPI handler */ + setidt(IPI_VECTOR, IDTVEC(ipi_intr_handler), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - /* Install an inter-CPU IPI for lazy pmap release */ - setidt(IPI_LAZYPMAP, IDTVEC(lazypmap), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - - /* Install an inter-CPU IPI for all-CPU rendezvous */ - setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - - /* Install an inter-CPU IPI for forcing an additional software trap */ - setidt(IPI_AST, IDTVEC(cpuast), - SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - /* Install an inter-CPU IPI for CPU stop/restart */ setidt(IPI_STOP, IDTVEC(cpustop), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - /* Set boot_cpu_id if needed. */ if (boot_cpu_id == -1) { boot_cpu_id = PCPU_GET(apic_id); @@ -923,7 +905,8 @@ smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) { u_int ncpu; - + u_int mask; + ncpu = mp_ncpus - 1; /* does not shootdown self */ if (ncpu < 1) return; /* no other cpus */ @@ -931,9 +914,24 @@ smp_tlb_addr1 = addr1; smp_tlb_addr2 = addr2; atomic_store_rel_int(&smp_tlb_wait, 0); - ipi_all_but_self(vector); + + /* Enable interrupts */ + /* Thread switching still disabled */ + +#ifdef IPI_NEED_TLB_INTR_ENABLED + enable_intr(); +#endif + mask = PCPU_GET(other_cpus); + + ipi_selected(mask,vector); + while (smp_tlb_wait < ncpu) ia32_pause(); +#ifdef IPI_NEED_TLB_INTR_ENABLED + /* disable interrupts */ + disable_intr(); +#endif + } /* @@ -998,6 +996,7 @@ ncpu = othercpus; if (ncpu < 1) return; + mask = PCPU_GET(other_cpus); } else { mask &= ~PCPU_GET(cpumask); if (mask == 0) @@ -1017,12 +1016,26 @@ smp_tlb_addr1 = addr1; smp_tlb_addr2 = addr2; atomic_store_rel_int(&smp_tlb_wait, 0); - if (mask == (u_int)-1) - ipi_all_but_self(vector); - else - ipi_selected(mask, vector); + + + /* Enable interrupts */ + /* Thread switching still disabled */ +#ifdef IPI_NEED_TLB_INTR_ENABLED + enable_intr(); +#endif + + ipi_selected(mask, vector); + while (smp_tlb_wait < ncpu) ia32_pause(); + + +#ifdef IPI_NEED_TLB_INTR_ENABLED + /* disable interrupts */ + disable_intr(); +#endif + + } void @@ -1098,20 +1111,6 @@ * For statclock, we send an IPI to all CPU's to have them call this * function. */ -void -forwarded_statclock(struct clockframe frame) -{ - struct thread *td; - - CTR0(KTR_SMP, "forwarded_statclock"); - td = curthread; - td->td_intr_nesting_level++; - if (profprocs != 0) - profclock(&frame); - if (pscnt == psdiv) - statclock(&frame); - td->td_intr_nesting_level--; -} void forward_statclock(void) @@ -1124,8 +1123,9 @@ return; map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); - if (map != 0) + if (map != 0) { ipi_selected(map, IPI_STATCLOCK); + } } /* @@ -1135,17 +1135,6 @@ * state and call hardclock_process() on the CPU receiving the clock interrupt * and then just use a simple IPI to handle any ast's if needed. */ -void -forwarded_hardclock(struct clockframe frame) -{ - struct thread *td; - - CTR0(KTR_SMP, "forwarded_hardclock"); - td = curthread; - td->td_intr_nesting_level++; - hardclock_process(&frame); - td->td_intr_nesting_level--; -} void forward_hardclock(void) @@ -1158,10 +1147,83 @@ return; map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); - if (map != 0) + if (map != 0) { ipi_selected(map, IPI_HARDCLOCK); + } } + + +void ipi_handler(struct clockframe frame) +{ + int cpu = PCPU_GET(cpuid); + u_int ipi_bitmap; + struct thread *td; + + ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]); + + critical_enter(); + + /* Nothing to do for AST */ + + if (ipi_bitmap & (1 << IPI_INVLTLB)) { + invltlb(); +#ifdef COUNT_XINVLTLB_HITS + xhits_gbl[cpu]++; +#endif + atomic_add_int(&smp_tlb_wait,1); + } + + if (ipi_bitmap & (1 << IPI_INVLPG)) { + invlpg(smp_tlb_addr1); +#ifdef COUNT_XINVLTLB_HITS + xhits_pg[cpu]++; +#endif + atomic_add_int(&smp_tlb_wait,1); + } + + if (ipi_bitmap & (1 << IPI_INVLRNG)) { + vm_offset_t addr; + for (addr = smp_tlb_addr1; addr < smp_tlb_addr2; addr += PAGE_SIZE) + invlpg(addr); +#ifdef COUNT_XINVLTLB_HITS + xhits_rng[cpu]++; +#endif + atomic_add_int(&smp_tlb_wait,1); + } + + if (ipi_bitmap & (1 << IPI_LAZYPMAP)) { + pmap_lazyfix_action(); + } + + if (ipi_bitmap & (1 << IPI_RENDEZVOUS)) { + smp_rendezvous_action(); + } + + if (ipi_bitmap & (1 << IPI_HARDCLOCK)) { + td = curthread; + td->td_intr_nesting_level++; + hardclock_process(&frame); + td->td_intr_nesting_level--; + } + + if (ipi_bitmap & (1 << IPI_STATCLOCK)) { + CTR0(KTR_SMP, "forwarded_statclock"); + + td = curthread; + td->td_intr_nesting_level++; + if (profprocs != 0) + profclock(&frame); + if (pscnt == psdiv) + statclock(&frame); + td->td_intr_nesting_level--; + } + + + critical_exit(); + + +} /* * send an IPI to a set of cpus. */ @@ -1169,17 +1231,41 @@ ipi_selected(u_int32_t cpus, u_int ipi) { int cpu; + u_int bitmap = 0; + u_int old_pending; + u_int new_pending; + + + + if (ipi <= IPI_MAX_HANDLER) { + bitmap = 1 << ipi; + ipi = IPI_VECTOR; + } CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; + cpus &= ~(1 << cpu); + KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu)); + + if (bitmap) { + do { + old_pending = cpu_ipi_pending[cpu]; + new_pending = old_pending | bitmap; + } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],old_pending, new_pending)); + + if (old_pending) + continue; + } + lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); - cpus &= ~(1 << cpu); } + } +#if 0 /* * send an IPI INTerrupt containing 'vector' to all CPUs, including myself */ @@ -1190,6 +1276,8 @@ CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); lapic_ipi_vectored(ipi, APIC_IPI_DEST_ALL); } +#endif + /* * send an IPI to all CPUs EXCEPT myself @@ -1197,11 +1285,12 @@ void ipi_all_but_self(u_int ipi) { - CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); - lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); + + ipi_selected(PCPU_GET(other_cpus), ipi); } +#if 0 /* * send an IPI to myself */ @@ -1212,6 +1301,7 @@ CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); lapic_ipi_vectored(ipi, APIC_IPI_DEST_SELF); } +#endif /* * This is called once the rest of the system is up and running and we're @@ -1320,3 +1410,18 @@ __asm __volatile("sti; hlt" : : : "memory"); return (retval); } + + + + + + + + + + + + + + + Index: i386/pmap.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/pmap.c,v retrieving revision 1.514 diff -u -r1.514 pmap.c --- i386/pmap.c 29 Oct 2004 19:10:46 -0000 1.514 +++ i386/pmap.c 15 Nov 2004 18:28:49 -0000 @@ -1282,7 +1282,6 @@ static u_int lazyptd; static volatile u_int lazywait; -void pmap_lazyfix_action(void); void pmap_lazyfix_action(void) @@ -1308,7 +1307,7 @@ static void pmap_lazyfix(pmap_t pmap) { - u_int mymask = PCPU_GET(cpumask); + u_int mymask; u_int mask; register u_int spins; @@ -1316,6 +1315,9 @@ spins = 50000000; mask = mask & -mask; /* Find least significant set bit */ mtx_lock_spin(&smp_ipi_mtx); + + mymask = PCPU_GET(cpumask); + #ifdef PAE lazyptd = vtophys(pmap->pm_pdpt); #else @@ -1328,12 +1330,23 @@ atomic_store_rel_int((u_int *)&lazymask, (u_int)&pmap->pm_active); atomic_store_rel_int(&lazywait, 0); + /* Enable interrupts */ + /* Thread switching still disabled */ +#ifdef IPI_NEED_TLB_INTR_ENABLED + enable_intr(); +#endif ipi_selected(mask, IPI_LAZYPMAP); while (lazywait == 0) { ia32_pause(); if (--spins == 0) break; } +#ifdef IPI_NEED_TLB_INTR_ENABLED + + /* disable interrupts */ + disable_intr(); +#endif + } mtx_unlock_spin(&smp_ipi_mtx); if (spins == 0) Index: include/apicvar.h =================================================================== RCS file: /cvsroot/src/sys/i386/include/apicvar.h,v retrieving revision 1.8 diff -u -r1.8 apicvar.h --- include/apicvar.h 23 Jun 2004 15:29:20 -0000 1.8 +++ include/apicvar.h 14 Nov 2004 21:20:05 -0000 @@ -87,14 +87,19 @@ #define APIC_THERMAL_INT (APIC_LOCAL_INTS + 2) #define APIC_IPI_INTS (APIC_LOCAL_INTS + 3) -#define IPI_AST APIC_IPI_INTS /* Generate software trap. */ -#define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */ -#define IPI_INVLPG (APIC_IPI_INTS + 2) -#define IPI_INVLRNG (APIC_IPI_INTS + 3) -#define IPI_LAZYPMAP (APIC_IPI_INTS + 4) /* Lazy pmap release. */ -#define IPI_HARDCLOCK (APIC_IPI_INTS + 8) /* Inter-CPU clock handling. */ -#define IPI_STATCLOCK (APIC_IPI_INTS + 9) -#define IPI_RENDEZVOUS (APIC_IPI_INTS + 10) /* Inter-CPU rendezvous. */ + +#define IPI_VECTOR APIC_IPI_INTS + +#define IPI_AST 0 /* Generate software trap. */ +#define IPI_INVLTLB 1 /* TLB Shootdown IPIs */ +#define IPI_INVLPG 2 +#define IPI_INVLRNG 3 +#define IPI_LAZYPMAP 4 /* Lazy pmap release. */ +#define IPI_HARDCLOCK 5 /* Inter-CPU clock handling. */ +#define IPI_STATCLOCK 6 +#define IPI_RENDEZVOUS 7 /* Inter-CPU rendezvous. */ +#define IPI_MAX_HANDLER 7 + #define IPI_STOP (APIC_IPI_INTS + 11) /* Stop CPU until restarted. */ #define APIC_SPURIOUS_INT 255 Index: include/smp.h =================================================================== RCS file: /cvsroot/src/sys/i386/include/smp.h,v retrieving revision 1.78 diff -u -r1.78 smp.h --- include/smp.h 11 Dec 2003 03:48:31 -0000 1.78 +++ include/smp.h 14 Nov 2004 22:26:30 -0000 @@ -52,15 +52,9 @@ /* IPI handlers */ inthand_t - IDTVEC(invltlb), /* TLB shootdowns - global */ - IDTVEC(invlpg), /* TLB shootdowns - 1 page */ - IDTVEC(invlrng), /* TLB shootdowns - page range */ - IDTVEC(hardclock), /* Forward hardclock() */ - IDTVEC(statclock), /* Forward statclock() */ - IDTVEC(cpuast), /* Additional software trap on other cpu */ - IDTVEC(cpustop), /* CPU stops & waits to be restarted */ - IDTVEC(rendezvous), /* handle CPU rendezvous */ - IDTVEC(lazypmap); /* handle lazy pmap release */ + IDTVEC(ipi_intr_handler), /* low level IPI handler */ + IDTVEC(cpustop); /* CPU stops & waits to be restarted */ + /* functions in mp_machdep.c */ void cpu_add(u_int apic_id, char boot_cpu); @@ -70,9 +64,7 @@ void ipi_all_but_self(u_int ipi); void ipi_self(u_int ipi); void forward_statclock(void); -void forwarded_statclock(struct clockframe frame); void forward_hardclock(void); -void forwarded_hardclock(struct clockframe frame); u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); void mp_topology(void); @@ -83,7 +75,8 @@ vm_offset_t endva); void smp_invltlb(void); void smp_masked_invltlb(u_int mask); - +void ipi_handler(struct clockframe frame); +void pmap_lazyfix_action(void); #endif /* !LOCORE */ #endif /* SMP */