--- //depot/vendor/freebsd/src/sys/i386/i386/apic_vector.s 2005/11/22 22:55:49 +++ //depot/user/jhb/acpipci/i386/i386/apic_vector.s 2005/11/23 18:43:46 @@ -44,24 +44,6 @@ #include "assym.s" /* - * Macros to create and destroy a trap frame. - */ -#define PUSH_FRAME \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; /* 8 ints */ \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs - -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp - -/* * I/O Interrupt Entry Point. Rather than having one entry point for * each interrupt source, we use one entry point for each 32-bit word * in the ISR. The handler determines the highest bit set in the ISR, @@ -73,11 +55,7 @@ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ PUSH_FRAME ; \ - movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ - movl %eax, %ds ; \ - movl %eax, %es ; \ - movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \ - movl %eax, %fs ; \ + SET_KERNEL_SREGS ; \ FAKE_MCOUNT(TF_EIP(%esp)) ; \ movl lapic, %edx ; /* pointer to local APIC */ \ movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \ @@ -123,20 +101,10 @@ SUPERALIGN_TEXT IDTVEC(timerint) 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 */ - + SET_KERNEL_SREGS FAKE_MCOUNT(TF_EIP(%esp)) - pushl $0 /* XXX convert trapframe to clockframe */ call lapic_handle_timer - addl $4, %esp /* XXX convert clockframe to trapframe */ MEXITCOUNT jmp doreti @@ -271,91 +239,33 @@ .text SUPERALIGN_TEXT IDTVEC(ipi_intr_bitmap_handler) - PUSH_FRAME - movl $KDSEL, %eax /* reload with kernel's data segment */ - movl %eax, %ds - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs + SET_KERNEL_SREGS 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 ipi_bitmap_handler - addl $4, %esp /* XXX convert clockframe to trapframe */ MEXITCOUNT jmp doreti /* - * Executed by a CPU when it receives an Xcpustop IPI from another CPU, - * - * - Signals its receipt. - * - Waits for permission to restart. - * - Signals its restart. + * Executed by a CPU when it receives an IPI_STOP from another CPU. */ .text SUPERALIGN_TEXT IDTVEC(cpustop) - pushl %ebp - movl %esp, %ebp - pushl %eax - pushl %ecx - pushl %edx - pushl %ds /* save current data segment */ - pushl %es - pushl %fs + PUSH_FRAME + SET_KERNEL_SREGS - movl $KDSEL, %eax - movl %eax, %ds /* use KERNEL data segment */ - movl %eax, %es - movl $KPSEL, %eax - movl %eax, %fs - movl lapic, %eax movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - movl PCPU(CPUID), %eax - imull $PCB_SIZE, %eax - leal CNAME(stoppcbs)(%eax), %eax - pushl %eax - call CNAME(savectx) /* Save process context */ - addl $4, %esp - - movl PCPU(CPUID), %eax + call cpustop_handler - lock - btsl %eax, CNAME(stopped_cpus) /* stopped_cpus |= (1<tf_eax, td); break; + case TRAP_INTERRUPT: case INTERRUPT: db_printf("--- interrupt"); break; --- //depot/vendor/freebsd/src/sys/i386/i386/exception.s 2005/07/13 11:35:17 +++ //depot/user/jhb/acpipci/i386/i386/exception.s 2005/11/18 21:13:20 @@ -74,6 +74,8 @@ MCOUNT_LABEL(user) MCOUNT_LABEL(btrap) +#define TRAP(a) pushl $(a) ; jmp alltraps + IDTVEC(div) pushl $0; TRAP(T_DIVIDE) IDTVEC(dbg) @@ -129,11 +131,7 @@ pushl %es pushl %fs alltraps_with_regs_pushed: - movl $KDSEL,%eax - movl %eax,%ds - movl %eax,%es - movl $KPSEL,%eax - movl %eax,%fs + SET_KERNEL_SREGS FAKE_MCOUNT(TF_EIP(%esp)) calltrap: call trap @@ -166,11 +164,7 @@ pushl %ds pushl %es pushl %fs - movl $KDSEL,%eax /* switch to kernel segments */ - movl %eax,%ds - movl %eax,%es - movl $KPSEL,%eax - movl %eax,%fs + SET_KERNEL_SREGS FAKE_MCOUNT(TF_EIP(%esp)) call syscall MEXITCOUNT @@ -191,11 +185,7 @@ pushl %ds pushl %es pushl %fs - movl $KDSEL,%eax /* switch to kernel segments */ - movl %eax,%ds - movl %eax,%es - movl $KPSEL,%eax - movl %eax,%fs + SET_KERNEL_SREGS FAKE_MCOUNT(TF_EIP(%esp)) call syscall MEXITCOUNT --- //depot/vendor/freebsd/src/sys/i386/i386/intr_machdep.c 2005/10/25 19:50:36 +++ //depot/user/jhb/acpipci/i386/i386/intr_machdep.c 2005/11/22 20:18:11 @@ -149,7 +149,7 @@ } void -intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe) +intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) { struct thread *td; struct intr_event *ie; @@ -196,7 +196,7 @@ * Execute fast interrupt handlers directly. * To support clock handlers, if a handler registers * with a NULL argument, then we pass it a pointer to - * an intrframe as its argument. + * a trapframe as its argument. */ td->td_intr_nesting_level++; thread = 0; @@ -207,11 +207,11 @@ continue; } CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__, - ih->ih_handler, ih->ih_argument == NULL ? iframe : + ih->ih_handler, ih->ih_argument == NULL ? frame : ih->ih_argument, ih->ih_name); if (ih->ih_argument == NULL) - ih->ih_handler(iframe); + ih->ih_handler(frame); else ih->ih_handler(ih->ih_argument); } --- //depot/vendor/freebsd/src/sys/i386/i386/local_apic.c 2005/11/02 20:15:36 +++ //depot/user/jhb/acpipci/i386/i386/local_apic.c 2005/11/22 20:18:11 @@ -608,13 +608,13 @@ } void -lapic_handle_intr(struct intrframe frame) +lapic_handle_intr(int vector, struct trapframe frame) { struct intsrc *isrc; - if (frame.if_vec == -1) + if (vector == -1) panic("Couldn't get vector from ISR!"); - isrc = intr_lookup_source(apic_idt_to_irq(frame.if_vec)); + isrc = intr_lookup_source(apic_idt_to_irq(vector)); intr_execute_handlers(isrc, &frame); } @@ -623,6 +623,10 @@ { struct lapic *la; + /* Send EOI first thing. */ + lapic_eoi(); + + /* Look up our local APIC structure for the tick counters. */ la = &lapics[PCPU_GET(apic_id)]; (*la->la_timer_count)++; critical_enter(); --- //depot/vendor/freebsd/src/sys/i386/i386/mp_machdep.c 2005/11/22 22:55:49 +++ //depot/user/jhb/acpipci/i386/i386/mp_machdep.c 2005/11/23 18:43:46 @@ -1276,15 +1276,29 @@ } int -ipi_nmi_handler() +ipi_nmi_handler(void) { - int cpu = PCPU_GET(cpuid); int cpumask = PCPU_GET(cpumask); if (!(ipi_nmi_pending & cpumask)) return 1; atomic_clear_int(&ipi_nmi_pending, cpumask); + cpustop_handler(); + return 0; +} + +#endif /* STOP_NMI */ + +/* + * Handle an IPI_STOP by saving our current context and spinning until we + * are resumed. + */ +void +cpustop_handler(void) +{ + int cpu = PCPU_GET(cpuid); + int cpumask = PCPU_GET(cpumask); savectx(&stoppcbs[cpu]); @@ -1302,11 +1316,7 @@ cpustop_restartfunc(); cpustop_restartfunc = NULL; } - - return 0; } - -#endif /* STOP_NMI */ /* * This is called once the rest of the system is up and running and we're --- //depot/vendor/freebsd/src/sys/i386/i386/pmap.c 2005/11/20 06:11:02 +++ //depot/user/jhb/acpipci/i386/i386/pmap.c 2005/11/23 18:45:41 @@ -106,6 +106,7 @@ #include "opt_cpu.h" #include "opt_pmap.h" #include "opt_msgbuf.h" +#include "opt_smp.h" #include "opt_xbox.h" #include @@ -1224,6 +1225,9 @@ { u_int mymask = PCPU_GET(cpumask); +#ifdef COUNT_IPIS + *ipi_lazypmap_counts[PCPU_GET(cpuid)]++; +#endif if (rcr3() == lazyptd) load_cr3(PCPU_GET(curpcb)->pcb_cr3); atomic_clear_int(lazymask, mymask); --- //depot/vendor/freebsd/src/sys/i386/include/apicvar.h 2005/11/02 20:15:36 +++ //depot/user/jhb/acpipci/i386/include/apicvar.h 2005/11/22 20:18:11 @@ -200,7 +200,7 @@ void lapic_ipi_raw(register_t icrlo, u_int dest); void lapic_ipi_vectored(u_int vector, int dest); int lapic_ipi_wait(int delay); -void lapic_handle_intr(struct intrframe frame); +void lapic_handle_intr(int vector, struct trapframe frame); void lapic_handle_timer(struct clockframe frame); void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked); --- //depot/vendor/freebsd/src/sys/i386/include/asmacros.h 2004/04/07 20:52:05 +++ //depot/user/jhb/acpipci/i386/include/asmacros.h 2005/11/18 21:13:20 @@ -59,12 +59,6 @@ #define NON_GPROF_ENTRY(name) GEN_ENTRY(name) #define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */ -#ifdef LOCORE -#define PCPU(member) %fs:PC_ ## member -#define PCPU_ADDR(member, reg) movl %fs:PC_PRVSPACE,reg; \ - addl $PC_ ## member,reg -#endif - #ifdef GPROF /* * __mcount is like [.]mcount except that doesn't require its caller to set @@ -136,12 +130,47 @@ #ifdef LOCORE /* - * Convenience macros for declaring interrupt entry points and trap - * stubs. + * Convenience macro for declaring interrupt entry points. */ #define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \ .type __CONCAT(X,name),@function; __CONCAT(X,name): -#define TRAP(a) pushl $(a) ; jmp alltraps + +/* + * Macros to create and destroy a trap frame. + */ +#define PUSH_FRAME \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; /* 8 ints */ \ + pushl %ds ; /* save data and extra segments ... */ \ + pushl %es ; \ + pushl %fs + +#define POP_FRAME \ + popl %fs ; \ + popl %es ; \ + popl %ds ; \ + popal ; \ + addl $4+4,%esp + +/* + * Access per-CPU data. + */ +#define PCPU(member) %fs:PC_ ## member + +#define PCPU_ADDR(member, reg) \ + movl %fs:PC_PRVSPACE, reg ; \ + addl $PC_ ## member, reg + +/* + * Setup the kernel segment registers. + */ +#define SET_KERNEL_SREGS \ + movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ + movl %eax, %ds ; \ + movl %eax, %es ; \ + movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \ + movl %eax, %fs #endif /* LOCORE */ --- //depot/vendor/freebsd/src/sys/i386/include/frame.h 2004/07/10 22:15:40 +++ //depot/user/jhb/acpipci/i386/include/frame.h 2005/11/22 20:18:11 @@ -97,36 +97,9 @@ int tf_vm86_gs; }; -/* Interrupt stack frame */ - -struct intrframe { - int if_vec; - int if_fs; - int if_es; - int if_ds; - int if_edi; - int if_esi; - int if_ebp; - int :32; - int if_ebx; - int if_edx; - int if_ecx; - int if_eax; - int :32; /* for compat with trap frame - trapno */ - int :32; /* for compat with trap frame - err */ - /* below portion defined in 386 hardware */ - int if_eip; - int if_cs; - int if_eflags; - /* below only when crossing rings (e.g. user to kernel) */ - int if_esp; - int if_ss; -}; - -/* frame of clock (same as interrupt frame) */ +/* frame of clock (same as trap frame) */ struct clockframe { - int cf_vec; int cf_fs; int cf_es; int cf_ds; @@ -149,7 +122,4 @@ int cf_ss; }; -#define CLOCK_TO_TRAPFRAME(frame) ((struct trapframe *)&(frame)->cf_fs) -#define INTR_TO_TRAPFRAME(frame) ((struct trapframe *)&(frame)->if_fs) - #endif /* _MACHINE_FRAME_H_ */ --- //depot/vendor/freebsd/src/sys/i386/include/intr_machdep.h 2005/11/02 20:15:36 +++ //depot/user/jhb/acpipci/i386/include/intr_machdep.h 2005/11/22 20:18:11 @@ -107,7 +107,7 @@ u_int is_index; }; -struct intrframe; +struct trapframe; extern struct mtx icu_lock; extern int elcr_found; @@ -121,7 +121,7 @@ void *arg, enum intr_type flags, void **cookiep); int intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol); -void intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe); +void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); struct intsrc *intr_lookup_source(int vector); int intr_register_source(struct intsrc *isrc); int intr_remove_handler(void *cookie); --- //depot/vendor/freebsd/src/sys/i386/include/smp.h 2005/11/22 22:35:32 +++ //depot/user/jhb/acpipci/i386/include/smp.h 2005/11/23 18:45:41 @@ -35,6 +35,13 @@ extern int boot_cpu_id; extern struct pcb stoppcbs[]; extern struct mtx smp_tlb_mtx; +#ifdef COUNT_IPIS +extern u_long *ipi_invltlb_counts[MAXCPU]; +extern u_long *ipi_invlrng_counts[MAXCPU]; +extern u_long *ipi_invlpg_counts[MAXCPU]; +extern u_long *ipi_rendezvous_counts[MAXCPU]; +extern u_long *ipi_lazypmap_counts[MAXCPU]; +#endif /* IPI handlers */ inthand_t @@ -48,6 +55,7 @@ /* functions in mp_machdep.c */ void cpu_add(u_int apic_id, char boot_cpu); +void cpustop_handler(void); void init_secondary(void); void ipi_selected(u_int cpus, u_int ipi); void ipi_all(u_int ipi); --- //depot/vendor/freebsd/src/sys/i386/isa/atpic.c 2005/10/25 19:50:36 +++ //depot/user/jhb/acpipci/i386/isa/atpic.c 2005/11/22 20:18:11 @@ -526,20 +526,19 @@ SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL) void -atpic_handle_intr(struct intrframe iframe) +atpic_handle_intr(u_int vector, struct trapframe frame) { struct intsrc *isrc; - KASSERT((u_int)iframe.if_vec < NUM_ISA_IRQS, - ("unknown int %d\n", iframe.if_vec)); - isrc = &atintrs[iframe.if_vec].at_intsrc; + KASSERT(vector < NUM_ISA_IRQS, + ("unknown int %u\n", vector)); + isrc = &atintrs[vector].at_intsrc; /* * If we don't have an event, see if this is a spurious * interrupt. */ - if (isrc->is_event == NULL && - (iframe.if_vec == 7 || iframe.if_vec == 15)) { + if (isrc->is_event == NULL && (vector == 7 || vector == 15)) { int port, isr; /* @@ -555,7 +554,7 @@ if ((isr & IRQ_MASK(7)) == 0) return; } - intr_execute_handlers(isrc, &iframe); + intr_execute_handlers(isrc, &frame); } #ifdef DEV_ISA --- //depot/vendor/freebsd/src/sys/i386/isa/atpic_vector.s 2004/05/26 07:45:25 +++ //depot/user/jhb/acpipci/i386/isa/atpic_vector.s 2005/11/18 21:13:20 @@ -47,17 +47,8 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; /* 8 ints */ \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs ; \ - movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ - movl %eax, %ds ; \ - movl %eax, %es ; \ - movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \ - movl %eax, %fs ; \ + PUSH_FRAME ; \ + SET_KERNEL_SREGS ; \ ; \ FAKE_MCOUNT(TF_EIP(%esp)) ; \ pushl $irq_num; /* pass the IRQ */ \ --- //depot/vendor/freebsd/src/sys/i386/isa/icu.h 2004/05/11 20:25:24 +++ //depot/user/jhb/acpipci/i386/isa/icu.h 2005/11/22 20:18:11 @@ -47,7 +47,7 @@ #define ICU_IMR_OFFSET 1 #endif -void atpic_handle_intr(struct intrframe iframe); +void atpic_handle_intr(u_int vector, struct trapframe frame); void atpic_startup(void); #endif /* !_I386_ISA_ICU_H_ */