From 5206bca10a37e28de61458411f2a06b938eb6820 Mon Sep 17 00:00:00 2001 From: Luoqi Chen Date: Wed, 28 Apr 1999 01:04:33 +0000 Subject: [PATCH] Enable vmspace sharing on SMP. Major changes are, - %fs register is added to trapframe and saved/restored upon kernel entry/exit. - Per-cpu pages are no longer mapped at the same virtual address. - Each cpu now has a separate gdt selector table. A new segment selector is added to point to per-cpu pages, per-cpu global variables are now accessed through this new selector (%fs). The selectors in gdt table are rearranged for cache line optimization. - fask_vfork is now on as default for both UP and SMP. - Some aio code cleanup. Reviewed by: Alan Cox John Dyson Julian Elischer Bruce Evans David Greenman --- sys/alpha/linux/linux_genassym.c | 3 +- sys/alpha/linux/linux_sysvec.c | 10 +- sys/amd64/amd64/apic_vector.S | 67 ++++++++--- sys/amd64/amd64/cpu_switch.S | 91 +++++++-------- sys/amd64/amd64/db_interface.c | 3 +- sys/amd64/amd64/db_trace.c | 4 +- sys/amd64/amd64/exception.S | 34 ++++-- sys/amd64/amd64/exception.s | 34 ++++-- sys/amd64/amd64/genassym.c | 63 ++++++----- sys/amd64/amd64/locore.S | 57 ++++------ sys/amd64/amd64/locore.s | 57 ++++------ sys/amd64/amd64/machdep.c | 185 ++++++++++++++++--------------- sys/amd64/amd64/mp_machdep.c | 167 +++++++++------------------- sys/amd64/amd64/mpboot.S | 6 +- sys/amd64/amd64/mptable.c | 167 +++++++++------------------- sys/amd64/amd64/pmap.c | 116 ++++++++----------- sys/amd64/amd64/support.S | 10 +- sys/amd64/amd64/support.s | 10 +- sys/amd64/amd64/swtch.s | 91 +++++++-------- sys/amd64/amd64/sys_machdep.c | 8 +- sys/amd64/amd64/trap.c | 11 +- sys/amd64/include/cpufunc.h | 34 +++++- sys/amd64/include/fpu.h | 6 +- sys/amd64/include/frame.h | 6 +- sys/amd64/include/md_var.h | 5 +- sys/amd64/include/mptable.h | 167 +++++++++------------------- sys/amd64/include/npx.h | 6 +- sys/amd64/include/pcb.h | 8 +- sys/amd64/include/pcpu.h | 68 +++++------- sys/amd64/include/proc.h | 4 +- sys/amd64/include/reg.h | 38 +++---- sys/amd64/include/segments.h | 25 +++-- sys/amd64/include/smp.h | 9 +- sys/amd64/include/tss.h | 11 +- sys/amd64/isa/atpic_vector.S | 15 ++- sys/amd64/isa/icu_vector.S | 15 ++- sys/amd64/isa/icu_vector.s | 15 ++- sys/compat/linux/linux_misc.c | 14 +-- sys/i386/i386/apic_vector.s | 67 ++++++++--- sys/i386/i386/db_interface.c | 3 +- sys/i386/i386/db_trace.c | 4 +- sys/i386/i386/exception.s | 34 ++++-- sys/i386/i386/genassym.c | 63 ++++++----- sys/i386/i386/globals.s | 85 ++++++++------ sys/i386/i386/locore.s | 57 ++++------ sys/i386/i386/machdep.c | 185 ++++++++++++++++--------------- sys/i386/i386/mp_machdep.c | 167 +++++++++------------------- sys/i386/i386/mpboot.s | 6 +- sys/i386/i386/mptable.c | 167 +++++++++------------------- sys/i386/i386/pmap.c | 116 ++++++++----------- sys/i386/i386/support.s | 10 +- sys/i386/i386/swtch.s | 91 +++++++-------- sys/i386/i386/sys_machdep.c | 8 +- sys/i386/i386/trap.c | 11 +- sys/i386/i386/vm86.c | 10 +- sys/i386/i386/vm86bios.s | 18 +-- sys/i386/include/asnames.h | 65 ++++++----- sys/i386/include/cpufunc.h | 34 +++++- sys/i386/include/frame.h | 6 +- sys/i386/include/globaldata.h | 68 +++++------- sys/i386/include/globals.h | 147 ++++++++++++++++++++++++ sys/i386/include/md_var.h | 5 +- sys/i386/include/mptable.h | 167 +++++++++------------------- sys/i386/include/npx.h | 6 +- sys/i386/include/pcb.h | 8 +- sys/i386/include/pcpu.h | 68 +++++------- sys/i386/include/proc.h | 4 +- sys/i386/include/reg.h | 38 +++---- sys/i386/include/segments.h | 25 +++-- sys/i386/include/smp.h | 9 +- sys/i386/include/tss.h | 11 +- sys/i386/include/vm86.h | 3 +- sys/i386/isa/apic_vector.s | 67 ++++++++--- sys/i386/isa/atpic_vector.s | 15 ++- sys/i386/isa/icu_vector.s | 15 ++- sys/i386/isa/ipl.s | 18 ++- sys/i386/isa/ipl_funcs.c | 3 +- sys/i386/linux/linux_genassym.c | 3 +- sys/i386/linux/linux_locore.s | 2 - sys/i386/linux/linux_misc.c | 14 +-- sys/i386/linux/linux_sysvec.c | 10 +- sys/i386/svr4/svr4_locore.s | 4 +- sys/i386/svr4/svr4_machdep.c | 11 ++ sys/kern/init_main.c | 5 +- sys/kern/kern_exit.c | 4 +- sys/kern/kern_fork.c | 22 +--- sys/kern/kern_linker.c | 4 +- sys/kern/subr_smp.c | 167 +++++++++------------------- sys/kern/subr_trap.c | 11 +- sys/kern/vfs_aio.c | 48 +------- sys/sys/proc.h | 12 +- sys/sys/smp.h | 9 +- 92 files changed, 1849 insertions(+), 2001 deletions(-) create mode 100644 sys/i386/include/globals.h diff --git a/sys/alpha/linux/linux_genassym.c b/sys/alpha/linux/linux_genassym.c index 76b8ced0eb66..99a88a510f6f 100644 --- a/sys/alpha/linux/linux_genassym.c +++ b/sys/alpha/linux/linux_genassym.c @@ -1,4 +1,4 @@ -/* $Id: linux_genassym.c,v 1.7 1998/02/01 18:47:56 bde Exp $ */ +/* $Id: linux_genassym.c,v 1.8 1998/07/29 15:50:41 bde Exp $ */ #include @@ -16,7 +16,6 @@ main() printf("#define\tLINUX_SIGF_HANDLER %u\n", OS(linux_sigframe, sf_handler)); printf("#define\tLINUX_SIGF_SC %u\n", OS(linux_sigframe, sf_sc)); - printf("#define\tLINUX_SC_FS %u\n", OS(linux_sigcontext, sc_fs)); printf("#define\tLINUX_SC_GS %u\n", OS(linux_sigcontext, sc_gs)); printf("#define\tLINUX_SC_EFLAGS %u\n", OS(linux_sigcontext, sc_eflags)); diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index d3a2f714613e..8584d96c895d 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.45 1999/02/04 21:20:13 newton Exp $ + * $Id: linux_sysvec.c,v 1.46 1999/04/19 14:14:14 peter Exp $ */ /* XXX we use functions that might not exist. */ @@ -249,8 +249,8 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) * Build the signal context to be used by sigreturn. */ frame.sf_sc.sc_mask = mask; - __asm("movl %%gs,%w0" : "=r" (frame.sf_sc.sc_gs)); - __asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs)); + frame.sf_sc.sc_gs = rgs(); + frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; frame.sf_sc.sc_ds = regs->tf_ds; frame.sf_sc.sc_edi = regs->tf_edi; @@ -286,6 +286,7 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; } @@ -359,7 +360,8 @@ linux_sigreturn(p, args) /* * Restore signal context. */ - /* %fs and %gs were restored by the trampoline. */ + /* %gs was restored by the trampoline. */ + regs->tf_fs = context.sc_fs; regs->tf_es = context.sc_es; regs->tf_ds = context.sc_ds; regs->tf_edi = context.sc_edi; diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 822375dad9d0..88340e6626b6 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.35 1999/04/10 19:19:02 tegge Exp $ + * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ */ @@ -58,10 +58,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL,%eax ; \ + movl %ax,%fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ pushl _intr_unit + (irq_num) * 4 ; \ GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -74,6 +77,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -92,10 +96,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL, %eax ; \ movl %ax, %ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -113,6 +120,7 @@ IDTVEC(vec_name) ; \ 1: ; \ MEXITCOUNT ; \ REL_FAST_INTR_LOCK ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -130,6 +138,7 @@ IDTVEC(vec_name) ; \ lock ; \ incb _intr_nesting_level ; /* ... really limit it ... */ \ sti ; /* to do this as early as possible */ \ + popl %fs ; /* discard most of thin frame ... */ \ MAYBE_POPL_ES ; /* discard most of thin frame ... */ \ popl %ecx ; /* ... original %ds ... */ \ popl %edx ; \ @@ -137,11 +146,14 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; movl $KDSEL, %eax ; \ movl %ax, %es ; \ - movl (2+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ - movl %ecx, (2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ + movl $KPSEL, %eax ; + movl %ax, %fs ; + movl (3+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ + movl %ecx, (3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4, %esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -158,9 +170,11 @@ IDTVEC(vec_name) ; \ pushl $0 ; /* dummy trap type */ \ pushal ; \ pushl %ds ; /* save data and extra segments ... */ \ - pushl %es + pushl %es ; \ + pushl %fs #define POP_FRAME \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ @@ -319,6 +333,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -344,7 +360,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -429,6 +445,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -453,7 +471,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -549,8 +567,11 @@ _Xinvltlb: pushl %eax #ifdef COUNT_XINVLTLB_HITS - ss + pushl %fs + movl $KPSEL, %eax + movl %ax, %fs movl _cpuid, %eax + popl %fs ss incl _xhits(,%eax,4) #endif /* COUNT_XINVLTLB_HITS */ @@ -576,7 +597,7 @@ _Xinvltlb: * * - Signals its receipt by setting bit cpuid in checkstate_probed_cpus. * - * stack: 0 -> ds, 4 -> ebx, 8 -> eax, 12 -> eip, 16 -> cs, 20 -> eflags + * stack: 0->ds, 4->fs, 8->ebx, 12->eax, 16->eip, 20->cs, 24->eflags */ .text @@ -589,19 +610,22 @@ _Xcpucheckstate: pushl %eax pushl %ebx pushl %ds /* save current data segment */ + pushl %fs movl $KDSEL, %eax movl %ax, %ds /* use KERNEL data segment */ + movl $KPSEL, %eax + movl %ax, %fs movl $0, lapic_eoi /* End Of Interrupt to APIC */ movl $0, %ebx - movl 16(%esp), %eax + movl 20(%esp), %eax andl $3, %eax cmpl $3, %eax je 1f #ifdef VM86 - testl $PSL_VM, 20(%esp) + testl $PSL_VM, 24(%esp) jne 1f #endif incl %ebx /* system or interrupt */ @@ -615,12 +639,13 @@ _Xcpucheckstate: movl %ebx, _checkstate_cpustate(,%eax,4) movl _curproc, %ebx movl %ebx, _checkstate_curproc(,%eax,4) - movl 12(%esp), %ebx + movl 16(%esp), %ebx movl %ebx, _checkstate_pc(,%eax,4) lock /* checkstate_probed_cpus |= (1<vm_map->pmap->p_pdir[] is painful in asm. - */ - movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ - -#if defined(SWTCH_OPTIM_STATS) - incl _tlb_flush_count -#endif - /* XXX: we have just changed the page tables.. reload.. */ - movl %ebx, %cr3 -#endif /* SMP */ - #ifdef VM86 - movl _my_tr, %esi +#ifdef SMP + movl _cpuid, %esi +#else + xorl %esi, %esi +#endif cmpl $0, PCB_EXT(%edx) /* has pcb extension? */ je 1f - movl $1, _private_tss /* mark use of private tss */ + btsl %esi, _private_tss /* mark use of private tss */ movl PCB_EXT(%edx), %edi /* new tss descriptor */ jmp 2f 1: #endif /* update common_tss.tss_esp0 pointer */ - movl $_common_tss, %eax movl %edx, %ebx /* pcb */ #ifdef VM86 addl $(UPAGES * PAGE_SIZE - 16), %ebx #else addl $(UPAGES * PAGE_SIZE), %ebx #endif /* VM86 */ - movl %ebx, TSS_ESP0(%eax) + movl %ebx, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 3f + btrl %esi, _private_tss + jae 3f +#ifdef SMP + movl $gd_common_tssd, %edi + addl %fs:0, %edi +#else movl $_common_tssd, %edi +#endif 2: + movl $GPROC0_SEL, %esi /* move correct tss descriptor into GDT slot, then reload tr */ leal _gdt(,%esi,8), %ebx /* entry in GDT */ movl 0(%edi), %eax @@ -738,9 +729,6 @@ swtch_com: #endif /* This must be done after loading the user LDT. */ - .globl cpu_switch_load_fs -cpu_switch_load_fs: - movl PCB_FS(%edx),%fs .globl cpu_switch_load_gs cpu_switch_load_gs: movl PCB_GS(%edx),%gs @@ -791,7 +779,6 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) - movl %fs,PCB_FS(%ecx) movl %gs,PCB_GS(%ecx) #if NNPX > 0 diff --git a/sys/amd64/amd64/db_interface.c b/sys/amd64/amd64/db_interface.c index 7f01f1d735e6..29985971b51a 100644 --- a/sys/amd64/amd64/db_interface.c +++ b/sys/amd64/amd64/db_interface.c @@ -23,7 +23,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: db_interface.c,v 1.42 1998/12/14 05:34:33 dillon Exp $ + * $Id: db_interface.c,v 1.43 1998/12/28 23:02:56 msmith Exp $ */ /* @@ -202,6 +202,7 @@ kdb_trap(type, code, regs) regs->tf_esi = ddb_regs.tf_esi; regs->tf_edi = ddb_regs.tf_edi; regs->tf_es = ddb_regs.tf_es & 0xffff; + regs->tf_fs = ddb_regs.tf_fs & 0xffff; regs->tf_cs = ddb_regs.tf_cs & 0xffff; regs->tf_ds = ddb_regs.tf_ds & 0xffff; return (1); diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c index 2ad054f2c4f8..6a361a0052f9 100644 --- a/sys/amd64/amd64/db_trace.c +++ b/sys/amd64/amd64/db_trace.c @@ -23,7 +23,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: db_trace.c,v 1.32 1999/01/27 23:45:38 dillon Exp $ + * $Id: db_trace.c,v 1.33 1999/01/28 01:59:50 dillon Exp $ */ #include @@ -47,8 +47,8 @@ struct db_variable db_regs[] = { { "cs", &ddb_regs.tf_cs, FCN_NULL }, { "ds", &ddb_regs.tf_ds, FCN_NULL }, { "es", &ddb_regs.tf_es, FCN_NULL }, -#if 0 { "fs", &ddb_regs.tf_fs, FCN_NULL }, +#if 0 { "gs", &ddb_regs.tf_gs, FCN_NULL }, #endif { "ss", &ddb_regs.tf_ss, FCN_NULL }, diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index a9286faf95e2..b87a1262dbdf 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $ + * $Id: exception.s,v 1.58 1999/04/16 21:22:12 peter Exp $ */ #include "npx.h" @@ -59,10 +59,12 @@ #define AVCPL_UNLOCK #endif /* SMP */ -#define KCSEL 0x08 /* kernel code selector */ -#define KDSEL 0x10 /* kernel data selector */ +#ifdef SMP +#define MOVL_KPSEL_EAX movl $KPSEL,%eax +#else +#define MOVL_KPSEL_EAX +#endif #define SEL_RPL_MASK 0x0003 -#define TRAPF_CS_OFF (13 * 4) .text @@ -149,10 +151,13 @@ IDTVEC(fpu) pushal pushl %ds pushl %es /* now stack frame is a trap frame */ + pushl %fs movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) #ifdef SMP MPLOCKED incl _cnt+V_TRAP @@ -198,11 +203,14 @@ _alltraps: pushal pushl %ds pushl %es + pushl %fs alltraps_with_regs_pushed: movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) calltrap: FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */ MPLOCKED incl _cnt+V_TRAP @@ -249,13 +257,16 @@ IDTVEC(syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */ movl %eax,TF_EFLAGS(%esp) movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL SYSCALL_LOCK ECPL_LOCK @@ -285,11 +296,14 @@ IDTVEC(int0x80_syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL ALTSYSCALL_LOCK ECPL_LOCK @@ -316,7 +330,9 @@ ENTRY(fork_trampoline) #ifdef SMP cmpl $0,_switchtime jne 1f - pushl $_switchtime + movl $gd_switchtime,%eax + addl %fs:0,%eax + pushl %eax call _microuptime popl %edx movl _ticks,%eax diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s index a9286faf95e2..b87a1262dbdf 100644 --- a/sys/amd64/amd64/exception.s +++ b/sys/amd64/amd64/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $ + * $Id: exception.s,v 1.58 1999/04/16 21:22:12 peter Exp $ */ #include "npx.h" @@ -59,10 +59,12 @@ #define AVCPL_UNLOCK #endif /* SMP */ -#define KCSEL 0x08 /* kernel code selector */ -#define KDSEL 0x10 /* kernel data selector */ +#ifdef SMP +#define MOVL_KPSEL_EAX movl $KPSEL,%eax +#else +#define MOVL_KPSEL_EAX +#endif #define SEL_RPL_MASK 0x0003 -#define TRAPF_CS_OFF (13 * 4) .text @@ -149,10 +151,13 @@ IDTVEC(fpu) pushal pushl %ds pushl %es /* now stack frame is a trap frame */ + pushl %fs movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) #ifdef SMP MPLOCKED incl _cnt+V_TRAP @@ -198,11 +203,14 @@ _alltraps: pushal pushl %ds pushl %es + pushl %fs alltraps_with_regs_pushed: movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) calltrap: FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */ MPLOCKED incl _cnt+V_TRAP @@ -249,13 +257,16 @@ IDTVEC(syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */ movl %eax,TF_EFLAGS(%esp) movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL SYSCALL_LOCK ECPL_LOCK @@ -285,11 +296,14 @@ IDTVEC(int0x80_syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL ALTSYSCALL_LOCK ECPL_LOCK @@ -316,7 +330,9 @@ ENTRY(fork_trampoline) #ifdef SMP cmpl $0,_switchtime jne 1f - pushl $_switchtime + movl $gd_switchtime,%eax + addl %fs:0,%eax + pushl %eax call _microuptime popl %edx movl _ticks,%eax diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 539f3e2c7db0..3525455c8ebf 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.64 1999/02/28 10:53:28 bde Exp $ + * $Id: genassym.c,v 1.65 1999/04/02 17:59:37 alc Exp $ */ #include "opt_vm86.h" @@ -66,9 +66,7 @@ #ifdef SMP #include #endif -#ifdef VM86 #include -#endif #include #define OS(s, m) ((u_int)offsetof(struct s, m)) @@ -126,7 +124,6 @@ main() printf("#define\tPCB_EIP %#x\n", OS(pcb, pcb_eip)); printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0)); printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt)); - printf("#define\tPCB_FS %#x\n", OS(pcb, pcb_fs)); printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs)); #ifdef VM86 printf("#define\tPCB_EXT %#x\n", OS(pcb, pcb_ext)); @@ -134,6 +131,7 @@ main() #ifdef SMP printf("#define\tPCB_MPNEST %#x\n", OS(pcb, pcb_mpnest)); #endif + printf("#define\tPCB_SPARE %#x\n", OS(pcb, __pcb_spare)); printf("#define\tU_PROF %#x\n", OS(user, u_stats.p_prof)); printf("#define\tU_PROFSCALE %#x\n", OS(user, u_stats.p_prof.pr_scale)); @@ -194,42 +192,43 @@ main() printf("#define\tBI_MODULEP %#x\n", OS(bootinfo, bi_modulep)); printf("#define\tGD_SIZEOF %u\n", sizeof(struct globaldata)); - printf("#define\tGD_CURPROC %#x\n", OS(globaldata, curproc)); - printf("#define\tGD_NPXPROC %#x\n", OS(globaldata, npxproc)); - printf("#define\tGD_CURPCB %#x\n", OS(globaldata, curpcb)); - printf("#define\tGD_COMMON_TSS %#x\n", OS(globaldata, common_tss)); - printf("#define\tGD_SWITCHTIME %#x\n", OS(globaldata, switchtime)); - printf("#define\tGD_SWITCHTICKS %#x\n", OS(globaldata, switchticks)); + printf("#define\tGD_CURPROC %#x\n", OS(globaldata, gd_curproc)); + printf("#define\tGD_NPXPROC %#x\n", OS(globaldata, gd_npxproc)); + printf("#define\tGD_CURPCB %#x\n", OS(globaldata, gd_curpcb)); + printf("#define\tGD_COMMON_TSS %#x\n", OS(globaldata, gd_common_tss)); + printf("#define\tGD_SWITCHTIME %#x\n", OS(globaldata, gd_switchtime)); + printf("#define\tGD_SWITCHTICKS %#x\n", OS(globaldata, gd_switchticks)); #ifdef VM86 - printf("#define\tGD_COMMON_TSSD %#x\n", OS(globaldata, common_tssd)); - printf("#define\tGD_PRIVATE_TSS %#x\n", OS(globaldata, private_tss)); - printf("#define\tGD_MY_TR %#x\n", OS(globaldata, my_tr)); + printf("#define\tGD_COMMON_TSSD %#x\n", OS(globaldata, gd_common_tssd)); #endif #ifdef USER_LDT - printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, currentldt)); + printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, gd_currentldt)); #endif #ifdef SMP - printf("#define\tGD_CPUID %#x\n", OS(globaldata, cpuid)); - printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, cpu_lockid)); - printf("#define\tGD_OTHER_CPUS %#x\n", OS(globaldata, other_cpus)); - printf("#define\tGD_MY_IDLEPTD %#x\n", OS(globaldata, my_idlePTD)); - printf("#define\tGD_SS_EFLAGS %#x\n", OS(globaldata, ss_eflags)); - printf("#define\tGD_PRV_CMAP1 %#x\n", OS(globaldata, prv_CMAP1)); - printf("#define\tGD_PRV_CMAP2 %#x\n", OS(globaldata, prv_CMAP2)); - printf("#define\tGD_PRV_CMAP3 %#x\n", OS(globaldata, prv_CMAP3)); - printf("#define\tGD_PRV_PMAP1 %#x\n", OS(globaldata, prv_PMAP1)); - printf("#define\tGD_INSIDE_INTR %#x\n", OS(globaldata, inside_intr)); + printf("#define\tGD_CPUID %#x\n", OS(globaldata, gd_cpuid)); + printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, gd_cpu_lockid)); + printf("#define\tGD_OTHER_CPUS %#x\n", OS(globaldata, gd_other_cpus)); + printf("#define\tGD_SS_EFLAGS %#x\n", OS(globaldata, gd_ss_eflags)); + printf("#define\tGD_INSIDE_INTR %#x\n", OS(globaldata, gd_inside_intr)); + printf("#define\tGD_PRV_CMAP1 %#x\n", OS(globaldata, gd_prv_CMAP1)); + printf("#define\tGD_PRV_CMAP2 %#x\n", OS(globaldata, gd_prv_CMAP2)); + printf("#define\tGD_PRV_CMAP3 %#x\n", OS(globaldata, gd_prv_CMAP3)); + printf("#define\tGD_PRV_PMAP1 %#x\n", OS(globaldata, gd_prv_PMAP1)); + printf("#define\tGD_PRV_CADDR1 %#x\n", OS(globaldata, gd_prv_CADDR1)); + printf("#define\tGD_PRV_CADDR2 %#x\n", OS(globaldata, gd_prv_CADDR2)); + printf("#define\tGD_PRV_CADDR3 %#x\n", OS(globaldata, gd_prv_CADDR3)); + printf("#define\tGD_PRV_PADDR1 %#x\n", OS(globaldata, gd_prv_PADDR1)); printf("#define\tPS_GLOBALDATA %#x\n", OS(privatespace, globaldata)); - printf("#define\tPS_PRVPT %#x\n", OS(privatespace, prvpt)); - printf("#define\tPS_LAPIC %#x\n", OS(privatespace, lapic)); printf("#define\tPS_IDLESTACK %#x\n", OS(privatespace, idlestack)); - printf("#define\tPS_IDLESTACK_TOP %#x\n", OS(privatespace, CPAGE1)); - printf("#define\tPS_CPAGE1 %#x\n", OS(privatespace, CPAGE1)); - printf("#define\tPS_CPAGE2 %#x\n", OS(privatespace, CPAGE2)); - printf("#define\tPS_CPAGE3 %#x\n", OS(privatespace, CPAGE3)); - printf("#define\tPS_PPAGE1 %#x\n", OS(privatespace, PPAGE1)); - printf("#define\tPS_IOAPICS %#x\n", OS(privatespace, ioapics)); + printf("#define\tPS_IDLESTACK_TOP %#x\n", sizeof(struct privatespace)); #endif + printf("#define\tKCSEL %#x\n", GSEL(GCODE_SEL, SEL_KPL)); + printf("#define\tKDSEL %#x\n", GSEL(GDATA_SEL, SEL_KPL)); +#ifdef SMP + printf("#define\tKPSEL %#x\n", GSEL(GPRIV_SEL, SEL_KPL)); +#endif + printf("#define\tGPROC0_SEL %#x\n", GPROC0_SEL); + return (0); } diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index 981418ba7ec0..63f74cc032ec 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.119 1999/01/30 15:38:47 kato Exp $ + * $Id: locore.s,v 1.120 1999/01/31 02:04:43 kato Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -102,7 +102,7 @@ HIDENAME(tmpstk): .globl _cpu,_cpu_vendor,_cpu_id,_bootinfo .globl _cpu_high, _cpu_feature -_cpu: .long 0 /* are we 386, 386sx, or 486 */ +_cpu: .long 0 /* are we 386, 386sx, or 486 */ _cpu_id: .long 0 /* stepping ID */ _cpu_high: .long 0 /* highest arg to CPUID */ _cpu_feature: .long 0 /* features */ @@ -113,12 +113,13 @@ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ #ifdef SMP + .globl _cpu0prvpage cpu0pp: .long 0 /* phys addr cpu0 private pg */ -cpu0pt: .long 0 /* phys addr cpu0 private pt */ - - .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ -_cpu0prvpt: .long 0 /* relocated version */ + + .globl _SMPpt +SMPptpa: .long 0 /* phys addr SMP page table */ +_SMPpt: .long 0 /* relocated version */ #endif /* SMP */ .globl _IdlePTD @@ -370,7 +371,6 @@ begin: movl _proc0paddr,%eax movl _IdlePTD, %esi movl %esi,PCB_CR3(%eax) - movl $_proc0,_curproc movl physfree, %esi pushl %esi /* value of first for init386(first) */ @@ -385,7 +385,7 @@ begin: pushl $PSL_USER /* eflags (IOPL 0, int enab) */ pushl __ucodesel /* cs */ pushl $0 /* eip - filled in by execve() */ - subl $(12*4),%esp /* space for rest of registers */ + subl $(13*4),%esp /* space for rest of registers */ pushl %esp /* call main with frame pointer */ call _main /* autoconfiguration, mountroot etc */ @@ -417,11 +417,11 @@ NON_GPROF_ENTRY(prepare_usermode) movl __ucodesel,%eax movl __udatasel,%ecx -#if 0 +#if 0 /* ds/es/fs are in trap frame */ movl %cx,%ds -#endif movl %cx,%es - movl %ax,%fs /* double map cs to fs */ + movl %cx,%fs +#endif movl %cx,%gs /* and ds to gs */ ret /* goto user! */ @@ -803,11 +803,11 @@ no_kernend: addl $KERNBASE, %esi movl %esi, R(_cpu0prvpage) /* relocated to KVM space */ -/* Allocate cpu0's private page table for mapping priv page, apic, etc */ +/* Allocate SMP page table page */ ALLOCPAGES(1) - movl %esi,R(cpu0pt) + movl %esi,R(SMPptpa) addl $KERNBASE, %esi - movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ + movl %esi, R(_SMPpt) /* relocated to KVM space */ #endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ @@ -887,25 +887,19 @@ map_read_write: movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global kmem FWIW */ - movl R(cpu0pt), %eax +/* Map SMP page table page into global kmem FWIW */ + movl R(SMPptpa), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table into private space */ +/* Map the private page into the SMP page table */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ - fillkpt(R(cpu0pt), $PG_RW) - -/* Map the page table page into private space */ - movl R(cpu0pt), %eax - movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* ... and put the page table table in the pde. */ - movl R(cpu0pt), %eax + movl R(SMPptpa), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) @@ -913,21 +907,12 @@ map_read_write: /* Fakeup VA for the local apic to allow early traps. */ ALLOCPAGES(1) movl %esi, %eax - movl $2, %ebx /* pte offset = 2 */ + movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */ movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* Initialize mp lock to allow early traps */ movl $1, R(_mp_lock) - -/* Initialize my_idlePTD to IdlePTD */ - movl R(cpu0pp), %eax - movl R(_IdlePTD), %ecx - movl %ecx,GD_MY_IDLEPTD(%eax) -/* Initialize IdlePTDS[0] */ - addl $KERNBASE, %ecx - movl %ecx, R(CNAME(IdlePTDS)) - #endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index 981418ba7ec0..63f74cc032ec 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.119 1999/01/30 15:38:47 kato Exp $ + * $Id: locore.s,v 1.120 1999/01/31 02:04:43 kato Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -102,7 +102,7 @@ HIDENAME(tmpstk): .globl _cpu,_cpu_vendor,_cpu_id,_bootinfo .globl _cpu_high, _cpu_feature -_cpu: .long 0 /* are we 386, 386sx, or 486 */ +_cpu: .long 0 /* are we 386, 386sx, or 486 */ _cpu_id: .long 0 /* stepping ID */ _cpu_high: .long 0 /* highest arg to CPUID */ _cpu_feature: .long 0 /* features */ @@ -113,12 +113,13 @@ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ #ifdef SMP + .globl _cpu0prvpage cpu0pp: .long 0 /* phys addr cpu0 private pg */ -cpu0pt: .long 0 /* phys addr cpu0 private pt */ - - .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ -_cpu0prvpt: .long 0 /* relocated version */ + + .globl _SMPpt +SMPptpa: .long 0 /* phys addr SMP page table */ +_SMPpt: .long 0 /* relocated version */ #endif /* SMP */ .globl _IdlePTD @@ -370,7 +371,6 @@ begin: movl _proc0paddr,%eax movl _IdlePTD, %esi movl %esi,PCB_CR3(%eax) - movl $_proc0,_curproc movl physfree, %esi pushl %esi /* value of first for init386(first) */ @@ -385,7 +385,7 @@ begin: pushl $PSL_USER /* eflags (IOPL 0, int enab) */ pushl __ucodesel /* cs */ pushl $0 /* eip - filled in by execve() */ - subl $(12*4),%esp /* space for rest of registers */ + subl $(13*4),%esp /* space for rest of registers */ pushl %esp /* call main with frame pointer */ call _main /* autoconfiguration, mountroot etc */ @@ -417,11 +417,11 @@ NON_GPROF_ENTRY(prepare_usermode) movl __ucodesel,%eax movl __udatasel,%ecx -#if 0 +#if 0 /* ds/es/fs are in trap frame */ movl %cx,%ds -#endif movl %cx,%es - movl %ax,%fs /* double map cs to fs */ + movl %cx,%fs +#endif movl %cx,%gs /* and ds to gs */ ret /* goto user! */ @@ -803,11 +803,11 @@ no_kernend: addl $KERNBASE, %esi movl %esi, R(_cpu0prvpage) /* relocated to KVM space */ -/* Allocate cpu0's private page table for mapping priv page, apic, etc */ +/* Allocate SMP page table page */ ALLOCPAGES(1) - movl %esi,R(cpu0pt) + movl %esi,R(SMPptpa) addl $KERNBASE, %esi - movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ + movl %esi, R(_SMPpt) /* relocated to KVM space */ #endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ @@ -887,25 +887,19 @@ map_read_write: movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global kmem FWIW */ - movl R(cpu0pt), %eax +/* Map SMP page table page into global kmem FWIW */ + movl R(SMPptpa), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table into private space */ +/* Map the private page into the SMP page table */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ - fillkpt(R(cpu0pt), $PG_RW) - -/* Map the page table page into private space */ - movl R(cpu0pt), %eax - movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* ... and put the page table table in the pde. */ - movl R(cpu0pt), %eax + movl R(SMPptpa), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) @@ -913,21 +907,12 @@ map_read_write: /* Fakeup VA for the local apic to allow early traps. */ ALLOCPAGES(1) movl %esi, %eax - movl $2, %ebx /* pte offset = 2 */ + movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */ movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* Initialize mp lock to allow early traps */ movl $1, R(_mp_lock) - -/* Initialize my_idlePTD to IdlePTD */ - movl R(cpu0pp), %eax - movl R(_IdlePTD), %ecx - movl %ecx,GD_MY_IDLEPTD(%eax) -/* Initialize IdlePTDS[0] */ - addl $KERNBASE, %ecx - movl %ecx, R(CNAME(IdlePTDS)) - #endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 712996e4c179..ac02b7abdbab 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.330 1999/04/19 14:14:12 peter Exp $ + * $Id: machdep.c,v 1.331 1999/04/26 08:57:51 peter Exp $ */ #include "apm.h" @@ -114,6 +114,7 @@ #include /* pcb.h included via sys/user.h */ #ifdef SMP #include +#include #endif #ifdef PERFMON #include @@ -552,6 +553,7 @@ sendsig(catcher, sig, mask, code) sf.sf_sc.sc_ds = regs->tf_ds; sf.sf_sc.sc_ss = regs->tf_ss; sf.sf_sc.sc_es = regs->tf_es; + sf.sf_sc.sc_fs = regs->tf_fs; sf.sf_sc.sc_isp = regs->tf_isp; /* @@ -616,6 +618,7 @@ sendsig(catcher, sig, mask, code) regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; } @@ -686,6 +689,7 @@ sigreturn(p, uap) tf->tf_vm86_gs = scp->sc_gs; tf->tf_ds = _udatasel; tf->tf_es = _udatasel; + tf->tf_fs = _udatasel; } else { #endif /* VM86 */ /* @@ -724,6 +728,7 @@ sigreturn(p, uap) } regs->tf_ds = scp->sc_ds; regs->tf_es = scp->sc_es; + regs->tf_fs = scp->sc_fs; #ifdef VM86 } #endif @@ -808,17 +813,16 @@ setregs(p, entry, stack, ps_strings) regs->tf_ss = _udatasel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_cs = _ucodesel; /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ regs->tf_ebx = ps_strings; - /* reset %fs and %gs as well */ - pcb->pcb_fs = _udatasel; + /* reset %gs as well */ pcb->pcb_gs = _udatasel; if (pcb == curpcb) { - __asm("movw %w0,%%fs" : : "r" (_udatasel)); - __asm("movw %w0,%%gs" : : "r" (_udatasel)); + load_gs(_udatasel); } /* @@ -887,7 +891,7 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, int _default_ldt; #ifdef SMP -union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ +union descriptor gdt[NGDT * NCPU]; /* global descriptor table */ #else union descriptor gdt[NGDT]; /* global descriptor table */ #endif @@ -898,11 +902,11 @@ union descriptor ldt[NLDT]; /* local descriptor table */ struct region_descriptor r_gdt, r_idt; #endif -extern struct i386tss common_tss; /* One tss per cpu */ #ifdef VM86 +#ifndef SMP extern struct segment_descriptor common_tssd; -extern int private_tss; /* flag indicating private tss */ -extern u_int my_tr; /* which task register setting */ +#endif +int private_tss; /* flag indicating private tss */ #endif /* VM86 */ #if defined(I586_CPU) && !defined(NO_F00F_HACK) @@ -917,11 +921,7 @@ extern struct user *proc0paddr; /* software prototypes -- in more palatable form */ -struct soft_segment_descriptor gdt_segs[ -#ifdef SMP - NGDT + NCPU -#endif - ] = { +struct soft_segment_descriptor gdt_segs[] = { /* GNULL_SEL 0 Null Descriptor */ { 0x0, /* segment base address */ 0x0, /* length */ @@ -949,7 +949,26 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GLDT_SEL 3 LDT Descriptor */ +/* GPRIV_SEL 3 SMP Per-Processor Private Data Descriptor */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GPROC0_SEL 4 Proc 0 Tss Descriptor */ +{ + 0x0, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GLDT_SEL 5 LDT Descriptor */ { (int) ldt, /* segment base address */ sizeof(ldt)-1, /* length - all address space */ SDT_SYSLDT, /* segment type */ @@ -958,35 +977,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GTGATE_SEL 4 Null Descriptor - Placeholder */ -{ 0x0, /* segment base address */ - 0x0, /* length - all address space */ - 0, /* segment type */ - 0, /* segment descriptor priority level */ - 0, /* segment descriptor present */ - 0, 0, - 0, /* default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GPANIC_SEL 5 Panic Tss Descriptor */ -{ (int) &dblfault_tss, /* segment base address */ - sizeof(struct i386tss)-1,/* length - all address space */ - SDT_SYS386TSS, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ -{ - (int) &common_tss, /* segment base address */ - sizeof(struct i386tss)-1,/* length - all address space */ - SDT_SYS386TSS, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GUSERLDT_SEL 7 User LDT Descriptor per process */ +/* GUSERLDT_SEL 6 User LDT Descriptor per process */ { (int) ldt, /* segment base address */ (512 * sizeof(union descriptor)-1), /* length */ SDT_SYSLDT, /* segment type */ @@ -995,7 +986,25 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */ +/* GTGATE_SEL 7 Null Descriptor - Placeholder */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GPANIC_SEL 8 Panic Tss Descriptor */ +{ (int) &dblfault_tss, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GAPMCODE32_SEL 9 APM BIOS 32-bit interface (32bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1004,7 +1013,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */ +/* GAPMCODE16_SEL 10 APM BIOS 32-bit interface (16bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1013,7 +1022,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMDATA_SEL 10 APM BIOS 32-bit interface (Data) */ +/* GAPMDATA_SEL 11 APM BIOS 32-bit interface (Data) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMRWA, /* segment type */ @@ -1159,11 +1168,6 @@ init386(first) atdevbase = ISA_HOLE_START + KERNBASE; - /* - * Initialize the console before we print anything out. - */ - cninit(); - /* * make gdt memory segments, the code segment goes up to end of the * page with etext in it, the data segment goes to the end of @@ -1175,28 +1179,31 @@ init386(first) */ gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1; gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; -#ifdef BDE_DEBUGGER -#define NGDT1 8 /* avoid overwriting db entries with APM ones */ -#else -#define NGDT1 (sizeof gdt_segs / sizeof gdt_segs[0]) -#endif - for (x = 0; x < NGDT1; x++) - ssdtosd(&gdt_segs[x], &gdt[x].sd); -#ifdef VM86 - common_tssd = gdt[GPROC0_SEL].sd; -#endif /* VM86 */ - #ifdef SMP - /* - * Spin these up now. init_secondary() grabs them. We could use - * #for(x,y,z) / #endfor cpp directives if they existed. - */ - for (x = 0; x < NCPU; x++) { - gdt_segs[NGDT + x] = gdt_segs[GPROC0_SEL]; - ssdtosd(&gdt_segs[NGDT + x], &gdt[NGDT + x].sd); - } + gdt_segs[GPRIV_SEL].ssd_limit = + i386_btop(sizeof(struct privatespace)) - 1; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[0].globaldata.gd_common_tss; + SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0]; +#else + gdt_segs[GPRIV_SEL].ssd_limit = i386_btop(0) - 1; + gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss; #endif + for (x = 0; x < NGDT; x++) { +#ifdef BDE_DEBUGGER + /* avoid overwriting db entries with APM ones */ + if (x >= GAPMCODE32_SEL && x <= GAPMDATA_SEL) + continue; +#endif + ssdtosd(&gdt_segs[x], &gdt[x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) gdt; + lgdt(&r_gdt); + /* make ldt memory segments */ /* * The data segment limit must not cover the user area because we @@ -1221,6 +1228,12 @@ init386(first) for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) ssdtosd(&ldt_segs[x], &ldt[x].sd); + _default_ldt = GSEL(GLDT_SEL, SEL_KPL); + lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif + /* exceptions */ for (x = 0; x < NIDT; x++) setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); @@ -1246,26 +1259,21 @@ init386(first) setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + r_idt.rd_limit = sizeof(idt) - 1; + r_idt.rd_base = (int) idt; + lidt(&r_idt); + + /* + * Initialize the console before we print anything out. + */ + cninit(); + #include "isa.h" #if NISA >0 isa_defaultirq(); #endif rand_initialize(); - r_gdt.rd_limit = sizeof(gdt) - 1; - r_gdt.rd_base = (int) gdt; - lgdt(&r_gdt); - - r_idt.rd_limit = sizeof(idt) - 1; - r_idt.rd_base = (int) idt; - lidt(&r_idt); - - _default_ldt = GSEL(GLDT_SEL, SEL_KPL); - lldt(_default_ldt); -#ifdef USER_LDT - currentldt = _default_ldt; -#endif - #ifdef DDB kdb_init(); if (boothowto & RB_KDB) @@ -1289,7 +1297,7 @@ init386(first) ltr(gsel_tss); #ifdef VM86 private_tss = 0; - my_tr = GPROC0_SEL; + common_tssd = gdt[GPROC0_SEL].sd; #endif dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = @@ -1607,6 +1615,7 @@ init386(first) #ifdef VM86 proc0.p_addr->u_pcb.pcb_ext = 0; #endif + SET_CURPROC(&proc0); /* Sigh, relocate physical addresses left from bootstrap */ if (bootinfo.bi_modulep) { @@ -1732,6 +1741,7 @@ fill_regs(p, regs) struct trapframe *tp; tp = p->p_md.md_regs; + regs->r_fs = tp->tf_fs; regs->r_es = tp->tf_es; regs->r_ds = tp->tf_ds; regs->r_edi = tp->tf_edi; @@ -1747,7 +1757,6 @@ fill_regs(p, regs) regs->r_esp = tp->tf_esp; regs->r_ss = tp->tf_ss; pcb = &p->p_addr->u_pcb; - regs->r_fs = pcb->pcb_fs; regs->r_gs = pcb->pcb_gs; return (0); } @@ -1764,6 +1773,7 @@ set_regs(p, regs) if (!EFLAGS_SECURE(regs->r_eflags, tp->tf_eflags) || !CS_SECURE(regs->r_cs)) return (EINVAL); + tp->tf_fs = regs->r_fs; tp->tf_es = regs->r_es; tp->tf_ds = regs->r_ds; tp->tf_edi = regs->r_edi; @@ -1779,7 +1789,6 @@ set_regs(p, regs) tp->tf_esp = regs->r_esp; tp->tf_ss = regs->r_ss; pcb = &p->p_addr->u_pcb; - pcb->pcb_fs = regs->r_fs; pcb->pcb_gs = regs->r_gs; return (0); } diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index eca2601a70b2..dcca437e8a10 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S index 7a5d431b65d0..8be76d7002c5 100644 --- a/sys/amd64/amd64/mpboot.S +++ b/sys/amd64/amd64/mpboot.S @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.8 1998/10/10 10:36:12 kato Exp $ + * $Id: mpboot.s,v 1.9 1999/04/10 22:58:29 tegge Exp $ */ #include "opt_vm86.h" @@ -76,12 +76,12 @@ NON_GPROF_ENTRY(MPentry) CHECKPOINT(0x36, 3) /* Now enable paging mode */ - movl _bootPTD-KERNBASE, %eax + movl _IdlePTD-KERNBASE, %eax movl %eax,%cr3 movl %cr0,%eax orl $CR0_PE|CR0_PG,%eax /* enable paging */ movl %eax,%cr0 /* let the games begin! */ - movl $_idlestack_top,%esp /* boot stack end loc. */ + movl _bootSTK,%esp /* boot stack end loc. */ pushl $mp_begin /* jump to high mem */ ret diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index eca2601a70b2..dcca437e8a10 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index bca25cc4a1ad..7aa92dedaa75 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.232 1999/04/23 20:29:58 dt Exp $ + * $Id: pmap.c,v 1.233 1999/04/25 18:40:05 alc Exp $ */ /* @@ -71,6 +71,8 @@ #include "opt_disable_pse.h" #include "opt_pmap.h" #include "opt_msgbuf.h" +#include "opt_vm86.h" +#include "opt_user_ldt.h" #include #include @@ -100,6 +102,9 @@ #if defined(SMP) || defined(APIC_IO) #include #include +#include +#include +#include #endif /* SMP || APIC_IO */ #define PMAP_KEEP_PDIRS @@ -146,7 +151,6 @@ static int protection_codes[8]; static struct pmap kernel_pmap_store; pmap_t kernel_pmap; -extern pd_entry_t my_idlePTD; vm_offset_t avail_start; /* PA of first available physical page */ vm_offset_t avail_end; /* PA of last available physical page */ @@ -184,19 +188,8 @@ static caddr_t CADDR2; static pt_entry_t *msgbufmap; struct msgbuf *msgbufp=0; -/* AIO support */ -extern struct vmspace *aiovmspace; - #ifdef SMP -extern char prv_CPAGE1[], prv_CPAGE2[], prv_CPAGE3[]; -extern pt_entry_t *prv_CMAP1, *prv_CMAP2, *prv_CMAP3; -extern pd_entry_t *IdlePTDS[]; -extern pt_entry_t SMP_prvpt[]; -#endif - -#ifdef SMP -extern unsigned int prv_PPAGE1[]; -extern pt_entry_t *prv_PMAP1; +extern pt_entry_t *SMPpt; #else static pt_entry_t *PMAP1 = 0; static unsigned *PADDR1 = 0; @@ -294,6 +287,7 @@ pmap_bootstrap(firstaddr, loadaddr) pt_entry_t *pte; #ifdef SMP int i, j; + struct globaldata *gd; #endif avail_start = firstaddr; @@ -404,12 +398,17 @@ pmap_bootstrap(firstaddr, loadaddr) ptditmp &= ~(NBPDR - 1); ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag; pdir4mb = ptditmp; + +#if !defined(SMP) /* * We can do the mapping here for the single processor * case. We simply ignore the old page table page from * now on. */ -#if !defined(SMP) + /* + * For SMP, we still need 4K pages to bootstrap APs, + * PSE will be enabled as soon as all APs are up. + */ PTD[KPTDI] = (pd_entry_t) ptditmp; kernel_pmap->pm_pdir[KPTDI] = (pd_entry_t) ptditmp; invltlb(); @@ -421,44 +420,46 @@ pmap_bootstrap(firstaddr, loadaddr) if (cpu_apic_address == 0) panic("pmap_bootstrap: no local apic!"); - /* 0 = private page */ - /* 1 = page table page */ - /* 2 = local apic */ - /* 16-31 = io apics */ - SMP_prvpt[2] = (pt_entry_t)(PG_V | PG_RW | pgeflag | + /* local apic is mapped on last page */ + SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag | (cpu_apic_address & PG_FRAME)); for (i = 0; i < mp_napics; i++) { - for (j = 0; j < 16; j++) { + for (j = 0; j < mp_napics; j++) { /* same page frame as a previous IO apic? */ - if (((vm_offset_t)SMP_prvpt[j + 16] & PG_FRAME) == + if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == (io_apic_address[0] & PG_FRAME)) { - ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace + + (NPTEPG-2-j)*PAGE_SIZE); break; } /* use this slot if available */ - if (((vm_offset_t)SMP_prvpt[j + 16] & PG_FRAME) == 0) { - SMP_prvpt[j + 16] = (pt_entry_t)(PG_V | PG_RW | + if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == 0) { + SMPpt[NPTEPG-2-j] = (pt_entry_t)(PG_V | PG_RW | pgeflag | (io_apic_address[i] & PG_FRAME)); - ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace + + (NPTEPG-2-j)*PAGE_SIZE); break; } } - if (j == 16) - panic("no space to map IO apic %d!", i); } /* BSP does this itself, AP's get it pre-set */ - prv_CMAP1 = &SMP_prvpt[3 + UPAGES]; - prv_CMAP2 = &SMP_prvpt[4 + UPAGES]; - prv_CMAP3 = &SMP_prvpt[5 + UPAGES]; - prv_PMAP1 = &SMP_prvpt[6 + UPAGES]; + gd = &SMP_prvspace[0].globaldata; + gd->gd_prv_CMAP1 = &SMPpt[1]; + gd->gd_prv_CMAP2 = &SMPpt[2]; + gd->gd_prv_CMAP3 = &SMPpt[3]; + gd->gd_prv_PMAP1 = &SMPpt[4]; + gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[0].PPAGE1; #endif invltlb(); - } +#ifdef SMP /* * Set 4mb pdir for mp startup, and global flags */ @@ -493,6 +494,7 @@ pmap_set_opt_bsp(void) pmap_set_opt((unsigned *)PTD); invltlb(); } +#endif /* * Initialize the pmap module. @@ -716,9 +718,9 @@ pmap_pte_quick(pmap, va) #ifdef SMP if ( ((* (unsigned *) prv_PMAP1) & PG_FRAME) != newpf) { * (unsigned *) prv_PMAP1 = newpf | PG_RW | PG_V; - cpu_invlpg(&prv_PPAGE1); + cpu_invlpg(prv_PADDR1); } - return prv_PPAGE1 + ((unsigned) index & (NPTEPG - 1)); + return prv_PADDR1 + ((unsigned) index & (NPTEPG - 1)); #else if ( ((* (unsigned *) PMAP1) & PG_FRAME) != newpf) { * (unsigned *) PMAP1 = newpf | PG_RW | PG_V; @@ -1122,7 +1124,6 @@ pmap_unuse_pt(pmap, va, mpte) return pmap_unwire_pte_hold(pmap, mpte); } -#if !defined(SMP) void pmap_pinit0(pmap) struct pmap *pmap; @@ -1136,14 +1137,6 @@ pmap_pinit0(pmap) TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); } -#else -void -pmap_pinit0(pmap) - struct pmap *pmap; -{ - pmap_pinit(pmap); -} -#endif /* * Initialize a preallocated and zeroed pmap structure, @@ -1189,6 +1182,9 @@ pmap_pinit(pmap) /* wire in kernel global address entries */ /* XXX copies current process, does not fill in MPPTDI */ bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE); +#ifdef SMP + pmap->pm_pdir[MPPTDI] = PTD[MPPTDI]; +#endif /* install self-referential address mapping entry */ *(unsigned *) (pmap->pm_pdir + PTDPTDI) = @@ -1430,9 +1426,6 @@ pmap_growkernel(vm_offset_t addr) int s; vm_offset_t ptppaddr; vm_page_t nkpg; -#ifdef SMP - int i; -#endif pd_entry_t newpdir; s = splhigh(); @@ -1468,23 +1461,12 @@ pmap_growkernel(vm_offset_t addr) newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M); pdir_pde(PTD, kernel_vm_end) = newpdir; -#ifdef SMP - for (i = 0; i < mp_ncpus; i++) { - if (IdlePTDS[i]) - pdir_pde(IdlePTDS[i], kernel_vm_end) = newpdir; - } -#endif - for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { if (p->p_vmspace) { pmap = vmspace_pmap(p->p_vmspace); *pmap_pde(pmap, kernel_vm_end) = newpdir; } } - if (aiovmspace != NULL) { - pmap = vmspace_pmap(aiovmspace); - *pmap_pde(pmap, kernel_vm_end) = newpdir; - } *pmap_pde(kernel_pmap, kernel_vm_end) = newpdir; kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); } @@ -2739,14 +2721,14 @@ pmap_zero_page(phys) #endif *(int *) prv_CMAP3 = PG_V | PG_RW | (phys & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE3); + cpu_invlpg(prv_CADDR3); #if defined(I686_CPU) if (cpu_class == CPUCLASS_686) - i686_pagezero(&prv_CPAGE3); + i686_pagezero(prv_CADDR3); else #endif - bzero(&prv_CPAGE3, PAGE_SIZE); + bzero(prv_CADDR3, PAGE_SIZE); *(int *) prv_CMAP3 = 0; #else @@ -2787,14 +2769,14 @@ pmap_zero_page_area(phys, off, size) #endif *(int *) prv_CMAP3 = PG_V | PG_RW | (phys & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE3); + cpu_invlpg(prv_CADDR3); #if defined(I686_CPU) if (cpu_class == CPUCLASS_686 && off == 0 && size == PAGE_SIZE) - i686_pagezero(&prv_CPAGE3); + i686_pagezero(prv_CADDR3); else #endif - bzero((char *)&prv_CPAGE3 + off, size); + bzero((char *)prv_CADDR3 + off, size); *(int *) prv_CMAP3 = 0; #else @@ -2838,10 +2820,10 @@ pmap_copy_page(src, dst) *(int *) prv_CMAP1 = PG_V | (src & PG_FRAME) | PG_A; *(int *) prv_CMAP2 = PG_V | PG_RW | (dst & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE1); - cpu_invlpg(&prv_CPAGE2); + cpu_invlpg(prv_CADDR1); + cpu_invlpg(prv_CADDR2); - bcopy(&prv_CPAGE1, &prv_CPAGE2, PAGE_SIZE); + bcopy(prv_CADDR1, prv_CADDR2, PAGE_SIZE); *(int *) prv_CMAP1 = 0; *(int *) prv_CMAP2 = 0; diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index cb9fd3e37588..7093dbb86df4 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -30,9 +30,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.61 1999/03/21 12:30:50 phk Exp $ + * $Id: support.s,v 1.62 1999/03/30 09:00:40 phk Exp $ */ +#include "opt_smp.h" #include "npx.h" #include @@ -42,8 +43,6 @@ #include "assym.s" -#define KDSEL 0x10 /* kernel data selector */ -#define KCSEL 0x8 /* kernel code selector */ #define IDXSHIFT 10 .data @@ -1495,9 +1494,12 @@ ENTRY(lgdt) movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - movl %ax,%fs movl %ax,%gs movl %ax,%ss +#ifdef SMP + movl $KPSEL,%eax +#endif + movl %ax,%fs /* reload code selector by turning return into intersegmental return */ movl (%esp),%eax diff --git a/sys/amd64/amd64/support.s b/sys/amd64/amd64/support.s index cb9fd3e37588..7093dbb86df4 100644 --- a/sys/amd64/amd64/support.s +++ b/sys/amd64/amd64/support.s @@ -30,9 +30,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.61 1999/03/21 12:30:50 phk Exp $ + * $Id: support.s,v 1.62 1999/03/30 09:00:40 phk Exp $ */ +#include "opt_smp.h" #include "npx.h" #include @@ -42,8 +43,6 @@ #include "assym.s" -#define KDSEL 0x10 /* kernel data selector */ -#define KCSEL 0x8 /* kernel code selector */ #define IDXSHIFT 10 .data @@ -1495,9 +1494,12 @@ ENTRY(lgdt) movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - movl %ax,%fs movl %ax,%gs movl %ax,%ss +#ifdef SMP + movl $KPSEL,%eax +#endif + movl %ax,%fs /* reload code selector by turning return into intersegmental return */ movl (%esp),%eax diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index 7e97a09981c7..ae4ca62319ea 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.77 1999/03/20 18:44:13 alc Exp $ + * $Id: swtch.s,v 1.78 1999/04/02 17:59:39 alc Exp $ */ #include "npx.h" @@ -258,25 +258,32 @@ _idle: /* when called, we have the mplock, intr disabled */ /* use our idleproc's "context" */ - movl _my_idlePTD,%ecx - movl %ecx,%cr3 + movl _IdlePTD, %ecx + movl %cr3, %eax + cmpl %ecx, %eax + je 2f #if defined(SWTCH_OPTIM_STATS) + decl _swtch_optim_stats incl _tlb_flush_count #endif + movl %ecx, %cr3 +2: /* Keep space for nonexisting return addr, or profiling bombs */ - movl $_idlestack_top-4,%ecx - movl %ecx,%esp + movl $gd_idlestack_top-4, %ecx + addl %fs:0, %ecx + movl %ecx, %esp /* update common_tss.tss_esp0 pointer */ -#ifdef VM86 - movl _my_tr, %esi -#endif /* VM86 */ movl %ecx, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 1f - movl $_common_tssd, %edi + movl _cpuid, %esi + btrl %esi, _private_tss + jae 1f + + movl $GPROC0_SEL, %esi + movl $gd_common_tssd, %edi + addl %fs:0, %edi /* move correct tss descriptor into GDT slot, then reload tr */ leal _gdt(,%esi,8), %ebx /* entry in GDT */ @@ -388,14 +395,14 @@ idle_loop: #endif /* update common_tss.tss_esp0 pointer */ -#ifdef VM86 - movl _my_tr, %esi -#endif /* VM86 */ movl %esp, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 1f + movl $0, %esi + btrl %esi, _private_tss + jae 1f + + movl $GPROC0_SEL, %esi movl $_common_tssd, %edi /* move correct tss descriptor into GDT slot, then reload tr */ @@ -477,7 +484,6 @@ ENTRY(cpu_switch) movl %ebp,PCB_EBP(%edx) movl %esi,PCB_ESI(%edx) movl %edi,PCB_EDI(%edx) - movl %fs,PCB_FS(%edx) movl %gs,PCB_GS(%edx) #ifdef SMP @@ -610,70 +616,55 @@ swtch_com: movl %eax,P_BACK(%ecx) /* isolate process to run */ movl P_ADDR(%ecx),%edx -#ifdef SMP - movl PCB_CR3(%edx),%ebx - /* Grab the private PT pointer from the outgoing process's PTD */ - movl $_PTD, %esi - movl 4*MPPTDI(%esi), %eax /* fetch cpu's prv pt */ -#else #if defined(SWTCH_OPTIM_STATS) incl _swtch_optim_stats #endif /* switch address space */ movl %cr3,%ebx cmpl PCB_CR3(%edx),%ebx - je 4f + je 4f #if defined(SWTCH_OPTIM_STATS) decl _swtch_optim_stats incl _tlb_flush_count #endif movl PCB_CR3(%edx),%ebx -#endif /* SMP */ movl %ebx,%cr3 4: -#ifdef SMP - /* Copy the private PT to the new process's PTD */ - /* XXX yuck, the _PTD changes when we switch, so we have to - * reload %cr3 after changing the address space. - * We need to fix this by storing a pointer to the virtual - * location of the per-process PTD in the PCB or something quick. - * Dereferencing proc->vm_map->pmap->p_pdir[] is painful in asm. - */ - movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ - -#if defined(SWTCH_OPTIM_STATS) - incl _tlb_flush_count -#endif - /* XXX: we have just changed the page tables.. reload.. */ - movl %ebx, %cr3 -#endif /* SMP */ - #ifdef VM86 - movl _my_tr, %esi +#ifdef SMP + movl _cpuid, %esi +#else + xorl %esi, %esi +#endif cmpl $0, PCB_EXT(%edx) /* has pcb extension? */ je 1f - movl $1, _private_tss /* mark use of private tss */ + btsl %esi, _private_tss /* mark use of private tss */ movl PCB_EXT(%edx), %edi /* new tss descriptor */ jmp 2f 1: #endif /* update common_tss.tss_esp0 pointer */ - movl $_common_tss, %eax movl %edx, %ebx /* pcb */ #ifdef VM86 addl $(UPAGES * PAGE_SIZE - 16), %ebx #else addl $(UPAGES * PAGE_SIZE), %ebx #endif /* VM86 */ - movl %ebx, TSS_ESP0(%eax) + movl %ebx, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 3f + btrl %esi, _private_tss + jae 3f +#ifdef SMP + movl $gd_common_tssd, %edi + addl %fs:0, %edi +#else movl $_common_tssd, %edi +#endif 2: + movl $GPROC0_SEL, %esi /* move correct tss descriptor into GDT slot, then reload tr */ leal _gdt(,%esi,8), %ebx /* entry in GDT */ movl 0(%edi), %eax @@ -738,9 +729,6 @@ swtch_com: #endif /* This must be done after loading the user LDT. */ - .globl cpu_switch_load_fs -cpu_switch_load_fs: - movl PCB_FS(%edx),%fs .globl cpu_switch_load_gs cpu_switch_load_gs: movl PCB_GS(%edx),%gs @@ -791,7 +779,6 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) - movl %fs,PCB_FS(%ecx) movl %gs,PCB_GS(%ecx) #if NNPX > 0 diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c index 9c3df3640565..4c40ed495898 100644 --- a/sys/amd64/amd64/sys_machdep.c +++ b/sys/amd64/amd64/sys_machdep.c @@ -31,12 +31,13 @@ * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.39 1999/01/28 01:59:50 dillon Exp $ + * $Id: sys_machdep.c,v 1.40 1999/04/27 11:14:33 phk Exp $ * */ #include "opt_user_ldt.h" #include "opt_vm86.h" +#include "opt_smp.h" #include #include @@ -54,6 +55,7 @@ #include #include /* pcb.h included by sys/user.h */ #include +#include #include /* for kernel_map */ @@ -261,7 +263,11 @@ set_user_ldt(struct pcb *pcb) { gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)pcb->pcb_ldt; gdt_segs[GUSERLDT_SEL].ssd_limit = (pcb->pcb_ldt_len * sizeof(union descriptor)) - 1; +#ifdef SMP + ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[cpuid * NGDT + GUSERLDT_SEL].sd); +#else ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[GUSERLDT_SEL].sd); +#endif lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); currentldt = GSEL(GUSERLDT_SEL, SEL_KPL); } diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index d08306e99ce8..c0807b0787a5 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.134 1999/03/09 20:20:09 phk Exp $ + * $Id: trap.c,v 1.135 1999/04/19 14:14:13 peter Exp $ */ /* @@ -101,8 +101,6 @@ #include "isa.h" #include "npx.h" -extern struct i386tss common_tss; - int (*pmath_emulate) __P((struct trapframe *)); extern void trap __P((struct trapframe frame)); @@ -480,11 +478,6 @@ kernel_trap: * (XXX) so that we can continue, and generate * a signal. */ - if (frame.tf_eip == (int)cpu_switch_load_fs) { - curpcb->pcb_fs = 0; - psignal(p, SIGBUS); - return; - } if (frame.tf_eip == (int)cpu_switch_load_gs) { curpcb->pcb_gs = 0; psignal(p, SIGBUS); @@ -496,6 +489,8 @@ kernel_trap: doreti_popl_ds_fault); MAYBE_DORETI_FAULT(doreti_popl_es, doreti_popl_es_fault); + MAYBE_DORETI_FAULT(doreti_popl_fs, + doreti_popl_fs_fault); if (curpcb && curpcb->pcb_onfault) { frame.tf_eip = (int)curpcb->pcb_onfault; return; diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index ce6bf0589001..c1f9f17c8487 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.84 1999/01/08 19:51:02 bde Exp $ + * $Id: cpufunc.h,v 1.85 1999/01/09 13:00:27 bde Exp $ */ /* @@ -426,6 +426,34 @@ wrmsr(u_int msr, u_int64_t newval) __asm __volatile(".byte 0x0f, 0x30" : : "A" (newval), "c" (msr)); } +static __inline u_int +rfs(void) +{ + u_int sel; + __asm __volatile("movl %%fs,%0" : "=r" (sel)); + return (sel); +} + +static __inline u_int +rgs(void) +{ + u_int sel; + __asm __volatile("movl %%gs,%0" : "=r" (sel)); + return (sel); +} + +static __inline void +load_fs(u_int sel) +{ + __asm __volatile("movl %0,%%fs" : : "r" (sel)); +} + +static __inline void +load_gs(u_int sel) +{ + __asm __volatile("movl %0,%%gs" : : "r" (sel)); +} + #else /* !__GNUC__ */ int breakpoint __P((void)); @@ -456,6 +484,10 @@ void setbits __P((volatile u_int *addr, u_int bits)); void wbinvd __P((void)); void write_eflags __P((u_int ef)); void wrmsr __P((u_int msr, u_int64_t newval)); +u_int rfs __P((void)); +u_int rgs __P((void)); +void load_fs __P((u_int sel)); +void load_gs __P((u_int sel)); #endif /* __GNUC__ */ diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h index a7608d5f7add..10384c6ebf9b 100644 --- a/sys/amd64/include/fpu.h +++ b/sys/amd64/include/fpu.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id: npx.h,v 1.13 1997/06/22 16:03:50 peter Exp $ + * $Id: npx.h,v 1.14 1997/07/20 11:06:44 bde Exp $ */ /* @@ -45,6 +45,8 @@ #ifndef _MACHINE_NPX_H_ #define _MACHINE_NPX_H_ +#include + /* Environment information of floating point unit */ struct env87 { long en_cw; /* control word (16bits) */ @@ -135,7 +137,9 @@ struct save87 { #endif #ifdef KERNEL +#ifndef npxproc extern struct proc *npxproc; +#endif int npxdna __P((void)); void npxexit __P((struct proc *p)); diff --git a/sys/amd64/include/frame.h b/sys/amd64/include/frame.h index 05092c2c4c07..7d70c14dff64 100644 --- a/sys/amd64/include/frame.h +++ b/sys/amd64/include/frame.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)frame.h 5.2 (Berkeley) 1/18/91 - * $Id: frame.h,v 1.14 1997/02/22 09:34:38 peter Exp $ + * $Id: frame.h,v 1.15 1997/08/09 00:03:12 dyson Exp $ */ #ifndef _MACHINE_FRAME_H_ @@ -51,6 +51,7 @@ */ struct trapframe { + int tf_fs; int tf_es; int tf_ds; int tf_edi; @@ -75,6 +76,7 @@ struct trapframe { /* Superset of trap frame, for traps from virtual-8086 mode */ struct trapframe_vm86 { + int tf_fs; int tf_es; int tf_ds; int tf_edi; @@ -106,6 +108,7 @@ struct trapframe_vm86 { struct intrframe { int if_vec; int if_ppl; + int if_fs; int if_es; int if_ds; int if_edi; @@ -132,6 +135,7 @@ struct intrframe { struct clockframe { int cf_vec; int cf_ppl; + int cf_fs; int cf_es; int cf_ds; int cf_edi; diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index fd7bcfd2c661..35b65455e244 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: md_var.h,v 1.27 1998/10/30 05:41:15 msmith Exp $ + * $Id: md_var.h,v 1.28 1999/01/08 16:29:58 bde Exp $ */ #ifndef _MACHINE_MD_VAR_H_ @@ -69,7 +69,6 @@ void bcopyb __P((const void *from, void *to, size_t len)); void busdma_swi __P((void)); void cpu_halt __P((void)); void cpu_reset __P((void)); -void cpu_switch_load_fs __P((void)) __asm(__STRING(cpu_switch_load_fs)); void cpu_switch_load_gs __P((void)) __asm(__STRING(cpu_switch_load_gs)); void doreti_iret __P((void)) __asm(__STRING(doreti_iret)); void doreti_iret_fault __P((void)) __asm(__STRING(doreti_iret_fault)); @@ -77,6 +76,8 @@ void doreti_popl_ds __P((void)) __asm(__STRING(doreti_popl_ds)); void doreti_popl_ds_fault __P((void)) __asm(__STRING(doreti_popl_ds_fault)); void doreti_popl_es __P((void)) __asm(__STRING(doreti_popl_es)); void doreti_popl_es_fault __P((void)) __asm(__STRING(doreti_popl_es_fault)); +void doreti_popl_fs __P((void)) __asm(__STRING(doreti_popl_fs)); +void doreti_popl_fs_fault __P((void)) __asm(__STRING(doreti_popl_fs_fault)); int fill_fpregs __P((struct proc *, struct fpreg *)); int fill_regs __P((struct proc *p, struct reg *regs)); void fillw __P((int /*u_short*/ pat, void *base, size_t cnt)); diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index eca2601a70b2..dcca437e8a10 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/amd64/include/npx.h b/sys/amd64/include/npx.h index a7608d5f7add..10384c6ebf9b 100644 --- a/sys/amd64/include/npx.h +++ b/sys/amd64/include/npx.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id: npx.h,v 1.13 1997/06/22 16:03:50 peter Exp $ + * $Id: npx.h,v 1.14 1997/07/20 11:06:44 bde Exp $ */ /* @@ -45,6 +45,8 @@ #ifndef _MACHINE_NPX_H_ #define _MACHINE_NPX_H_ +#include + /* Environment information of floating point unit */ struct env87 { long en_cw; /* control word (16bits) */ @@ -135,7 +137,9 @@ struct save87 { #endif #ifdef KERNEL +#ifndef npxproc extern struct proc *npxproc; +#endif int npxdna __P((void)); void npxexit __P((struct proc *p)); diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h index d76217ff3b8e..9ab0856137a7 100644 --- a/sys/amd64/include/pcb.h +++ b/sys/amd64/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.25 1997/10/10 12:40:09 peter Exp $ + * $Id: pcb.h,v 1.26 1998/02/03 21:27:50 bde Exp $ */ #ifndef _I386_PCB_H_ @@ -43,6 +43,7 @@ /* * Intel 386 process control block */ +#include #include struct pcb { @@ -64,14 +65,13 @@ struct pcb { #else u_long pcb_mpnest_dontuse; #endif - int pcb_fs; int pcb_gs; #ifdef VM86 struct pcb_ext *pcb_ext; /* optional pcb extension */ #else struct pcb_ext *pcb_ext_dontuse; #endif - u_long __pcb_spare[1]; /* adjust to avoid core dump size changes */ + u_long __pcb_spare[2]; /* adjust to avoid core dump size changes */ }; /* @@ -83,7 +83,9 @@ struct md_coredump { #ifdef KERNEL +#ifndef curpcb extern struct pcb *curpcb; /* our current running pcb */ +#endif void savectx __P((struct pcb *)); #endif diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index ec5879940ecd..f1d4fdd0ffa1 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.6 1998/08/18 07:47:12 msmith Exp $ + * $Id: globaldata.h,v 1.7 1999/02/22 15:13:34 bde Exp $ */ /* @@ -39,31 +39,33 @@ * other processors" */ struct globaldata { - struct proc *curproc; - struct proc *npxproc; - struct pcb *curpcb; - struct i386tss common_tss; - struct timeval switchtime; - int switchticks; + struct privatespace *gd_prvspace; /* self-reference */ + struct proc *gd_curproc; + struct proc *gd_npxproc; + struct pcb *gd_curpcb; + struct timeval gd_switchtime; + struct i386tss gd_common_tss; + int gd_switchticks; #ifdef VM86 - struct segment_descriptor common_tssd; - u_int private_tss; - u_int my_tr; + struct segment_descriptor gd_common_tssd; #endif #ifdef USER_LDT - int currentldt; + int gd_currentldt; #endif #ifdef SMP - u_int cpuid; - u_int cpu_lockid; - u_int other_cpus; - pd_entry_t *my_idlePTD; - u_int ss_eflags; - pt_entry_t *prv_CMAP1; - pt_entry_t *prv_CMAP2; - pt_entry_t *prv_CMAP3; - pt_entry_t *prv_PMAP1; - int inside_intr; + u_int gd_cpuid; + u_int gd_cpu_lockid; + u_int gd_other_cpus; + int gd_inside_intr; + u_int gd_ss_eflags; + pt_entry_t *gd_prv_CMAP1; + pt_entry_t *gd_prv_CMAP2; + pt_entry_t *gd_prv_CMAP3; + pt_entry_t *gd_prv_PMAP1; + caddr_t gd_prv_CADDR1; + caddr_t gd_prv_CADDR2; + caddr_t gd_prv_CADDR3; + unsigned *gd_prv_PADDR1; #endif }; @@ -78,28 +80,16 @@ struct privatespace { struct globaldata globaldata; char __filler0[PAGE_SIZE - sizeof(struct globaldata)]; - /* page 1 - page table page */ - pt_entry_t prvpt[NPTEPG]; - - /* page 2 - local apic mapping */ - lapic_t lapic; - char __filler1[PAGE_SIZE - sizeof(lapic_t)]; - - /* page 3..2+UPAGES - idle stack (UPAGES pages) */ - char idlestack[UPAGES * PAGE_SIZE]; - - /* page 3+UPAGES..6+UPAGES - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ + /* page 1..4 - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ char CPAGE1[PAGE_SIZE]; char CPAGE2[PAGE_SIZE]; char CPAGE3[PAGE_SIZE]; char PPAGE1[PAGE_SIZE]; - /* page 7+UPAGES..15 - spare, unmapped */ - char __filler2[(9-UPAGES) * PAGE_SIZE]; - - /* page 16-31 - space for IO apics */ - char ioapics[16 * PAGE_SIZE]; - - /* page 32-47 - maybe other cpu's globaldata pages? */ + /* page 5..4+UPAGES - idle stack (UPAGES pages) */ + char idlestack[UPAGES * PAGE_SIZE]; }; + +extern struct privatespace SMP_prvspace[]; + #endif diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h index e7a4744a03b5..ae6cd6337bc3 100644 --- a/sys/amd64/include/proc.h +++ b/sys/amd64/include/proc.h @@ -31,12 +31,14 @@ * SUCH DAMAGE. * * from: @(#)proc.h 7.1 (Berkeley) 5/15/91 - * $Id: proc.h,v 1.7 1997/02/22 09:34:59 peter Exp $ + * $Id: proc.h,v 1.8 1997/05/07 19:55:13 peter Exp $ */ #ifndef _MACHINE_PROC_H_ #define _MACHINE_PROC_H_ +#include + /* * Machine-dependent part of the proc structure for i386. */ diff --git a/sys/amd64/include/reg.h b/sys/amd64/include/reg.h index 28466a838bc8..247011646fa5 100644 --- a/sys/amd64/include/reg.h +++ b/sys/amd64/include/reg.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)reg.h 5.5 (Berkeley) 1/18/91 - * $Id: reg.h,v 1.16 1998/09/14 22:43:40 jdp Exp $ + * $Id: reg.h,v 1.17 1999/04/03 22:19:59 jdp Exp $ */ #ifndef _MACHINE_REG_H_ @@ -51,22 +51,23 @@ * stopped accessing the registers in the trap frame via PT_{READ,WRITE}_U * and we can stop supporting the user area soon. */ -#define tES (0) -#define tDS (1) -#define tEDI (2) -#define tESI (3) -#define tEBP (4) -#define tISP (5) -#define tEBX (6) -#define tEDX (7) -#define tECX (8) -#define tEAX (9) -#define tERR (11) -#define tEIP (12) -#define tCS (13) -#define tEFLAGS (14) -#define tESP (15) -#define tSS (16) +#define tFS (0) +#define tES (1) +#define tDS (2) +#define tEDI (3) +#define tESI (4) +#define tEBP (5) +#define tISP (6) +#define tEBX (7) +#define tEDX (8) +#define tECX (9) +#define tEAX (10) +#define tERR (12) +#define tEIP (13) +#define tCS (14) +#define tEFLAGS (15) +#define tESP (16) +#define tSS (17) /* * Indices for registers in `struct regs' only. @@ -75,13 +76,13 @@ * other registers in application interfaces that copy all the registers * to or from a `struct regs'. */ -#define tFS (17) #define tGS (18) /* * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS. */ struct reg { + unsigned int r_fs; unsigned int r_es; unsigned int r_ds; unsigned int r_edi; @@ -99,7 +100,6 @@ struct reg { unsigned int r_eflags; unsigned int r_esp; unsigned int r_ss; - unsigned int r_fs; unsigned int r_gs; }; diff --git a/sys/amd64/include/segments.h b/sys/amd64/include/segments.h index 674b0f38c28e..eaecfa322c5f 100644 --- a/sys/amd64/include/segments.h +++ b/sys/amd64/include/segments.h @@ -35,12 +35,14 @@ * SUCH DAMAGE. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 - * $Id: segments.h,v 1.17 1997/08/21 06:32:49 charnier Exp $ + * $Id: segments.h,v 1.18 1999/01/28 11:45:49 newton Exp $ */ #ifndef _MACHINE_SEGMENTS_H_ #define _MACHINE_SEGMENTS_H_ +#include + /* * 386 Segmentation Data Structures and definitions * William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989 @@ -207,19 +209,20 @@ struct region_descriptor { #define GNULL_SEL 0 /* Null Descriptor */ #define GCODE_SEL 1 /* Kernel Code Descriptor */ #define GDATA_SEL 2 /* Kernel Data Descriptor */ -#define GLDT_SEL 3 /* LDT - eventually one per process */ -#define GTGATE_SEL 4 /* Process task switch gate */ -#define GPANIC_SEL 5 /* Task state to consider panic from */ -#define GPROC0_SEL 6 /* Task state process slot zero and up */ -#define GUSERLDT_SEL 7 /* User LDT */ -#define GAPMCODE32_SEL 8 /* APM BIOS 32-bit interface (32bit Code) */ -#define GAPMCODE16_SEL 9 /* APM BIOS 32-bit interface (16bit Code) */ -#define GAPMDATA_SEL 10 /* APM BIOS 32-bit interface (Data) */ +#define GPRIV_SEL 3 /* SMP Per-Processor Private Data */ +#define GPROC0_SEL 4 /* Task state process slot zero and up */ +#define GLDT_SEL 5 /* LDT - eventually one per process */ +#define GUSERLDT_SEL 6 /* User LDT */ +#define GTGATE_SEL 7 /* Process task switch gate */ +#define GPANIC_SEL 8 /* Task state to consider panic from */ +#define GAPMCODE32_SEL 9 /* APM BIOS 32-bit interface (32bit Code) */ +#define GAPMCODE16_SEL 10 /* APM BIOS 32-bit interface (16bit Code) */ +#define GAPMDATA_SEL 11 /* APM BIOS 32-bit interface (Data) */ #ifdef BDE_DEBUGGER #define NGDT 18 /* some of 11-17 are reserved for debugger */ #else -#define NGDT (GAPMDATA_SEL + 1) +#define NGDT 12 #endif /* @@ -237,7 +240,9 @@ struct region_descriptor { #define NLDT (LBSDICALLS_SEL + 1) #ifdef KERNEL +#ifndef currentldt extern int currentldt; +#endif extern int _default_ldt; extern union descriptor gdt[]; extern struct soft_segment_descriptor gdt_segs[]; diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 0f4f915366b6..3750c72011eb 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ + * $Id: smp.h,v 1.44 1998/09/06 22:41:40 tegge Exp $ * */ @@ -112,7 +112,6 @@ struct apic_intmapinfo { }; extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; -extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; /* functions in mp_machdep.c */ @@ -175,12 +174,6 @@ extern int invltlb_ok; extern int smp_active; extern volatile int smp_idle_loops; -/* 'private' global data in locore.s */ -extern volatile u_int cpuid; -extern volatile u_int cpu_lockid; -extern int inside_intr; -extern volatile u_int other_cpus; - #endif /* !LOCORE */ #endif /* SMP || APIC_IO */ #endif /* KERNEL */ diff --git a/sys/amd64/include/tss.h b/sys/amd64/include/tss.h index 565defab8cb7..636133a9a870 100644 --- a/sys/amd64/include/tss.h +++ b/sys/amd64/include/tss.h @@ -34,12 +34,14 @@ * SUCH DAMAGE. * * from: @(#)tss.h 5.4 (Berkeley) 1/18/91 - * $Id$ + * $Id: tss.h,v 1.8 1997/02/22 09:35:20 peter Exp $ */ #ifndef _MACHINE_TSS_H_ #define _MACHINE_TSS_H_ 1 +#include + /* * Intel 386 Context Data Type */ @@ -79,4 +81,11 @@ struct i386tss { int tss_ioopt; /* options & io offset bitmap: currently zero */ /* XXX unimplemented .. i/o permission bitmap */ }; + +#ifdef KERNEL +#ifndef common_tss +extern struct i386tss common_tss; +#endif +#endif + #endif /* _MACHINE_TSS_H_ */ diff --git a/sys/amd64/isa/atpic_vector.S b/sys/amd64/isa/atpic_vector.S index 2dcda028a8bf..446030303231 100644 --- a/sys/amd64/isa/atpic_vector.S +++ b/sys/amd64/isa/atpic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.9 1998/08/11 17:01:32 bde Exp $ + * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ */ /* @@ -94,11 +94,13 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%es ; \ - movl (2+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ - movl %ecx,(2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ + movl %ax,%fs ; \ + movl (3+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ + movl %ecx,(3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4,%esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -113,9 +115,11 @@ IDTVEC(vec_name) ; \ pushal ; \ pushl %ds ; /* save our data and extra segments ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; /* ... and reload with kernel's own ... */ \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ + movl %ax,%fs ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -126,7 +130,7 @@ IDTVEC(vec_name) ; \ jne 2f ; \ incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ @@ -152,6 +156,7 @@ __CONCAT(Xresume,irq_num): ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ diff --git a/sys/amd64/isa/icu_vector.S b/sys/amd64/isa/icu_vector.S index 2dcda028a8bf..446030303231 100644 --- a/sys/amd64/isa/icu_vector.S +++ b/sys/amd64/isa/icu_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.9 1998/08/11 17:01:32 bde Exp $ + * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ */ /* @@ -94,11 +94,13 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%es ; \ - movl (2+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ - movl %ecx,(2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ + movl %ax,%fs ; \ + movl (3+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ + movl %ecx,(3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4,%esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -113,9 +115,11 @@ IDTVEC(vec_name) ; \ pushal ; \ pushl %ds ; /* save our data and extra segments ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; /* ... and reload with kernel's own ... */ \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ + movl %ax,%fs ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -126,7 +130,7 @@ IDTVEC(vec_name) ; \ jne 2f ; \ incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ @@ -152,6 +156,7 @@ __CONCAT(Xresume,irq_num): ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ diff --git a/sys/amd64/isa/icu_vector.s b/sys/amd64/isa/icu_vector.s index 2dcda028a8bf..446030303231 100644 --- a/sys/amd64/isa/icu_vector.s +++ b/sys/amd64/isa/icu_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.9 1998/08/11 17:01:32 bde Exp $ + * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ */ /* @@ -94,11 +94,13 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%es ; \ - movl (2+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ - movl %ecx,(2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ + movl %ax,%fs ; \ + movl (3+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \ + movl %ecx,(3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4,%esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -113,9 +115,11 @@ IDTVEC(vec_name) ; \ pushal ; \ pushl %ds ; /* save our data and extra segments ... */ \ pushl %es ; \ + pushl %fs ; \ movl $KDSEL,%eax ; /* ... and reload with kernel's own ... */ \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ + movl %ax,%fs ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -126,7 +130,7 @@ IDTVEC(vec_name) ; \ jne 2f ; \ incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ @@ -152,6 +156,7 @@ __CONCAT(Xresume,irq_num): ; \ 2: ; \ /* XXX skip mcounting here to avoid double count */ \ orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 68a2d4308f7e..e01693ad0aef 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.55 1999/04/27 11:15:32 phk Exp $ + * $Id: linux_misc.c,v 1.56 1999/04/27 12:21:04 phk Exp $ */ #include @@ -531,18 +531,18 @@ select_out: int linux_getpgid(struct proc *p, struct linux_getpgid_args *args) { - struct proc *curproc; + struct proc *curp; #ifdef DEBUG printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); #endif if (args->pid != p->p_pid) { - if (!(curproc = pfind(args->pid))) + if (!(curp = pfind(args->pid))) return ESRCH; } else - curproc = p; - p->p_retval[0] = curproc->p_pgid; + curp = p; + p->p_retval[0] = curp->p_pgid; return 0; } @@ -576,10 +576,6 @@ linux_clone(struct proc *p, struct linux_clone_args *args) vm_offset_t start; struct rfork_args rf_args; -#ifdef SMP - printf("linux_clone(%d): does not work with SMP yet\n", p->p_pid); - return (EOPNOTSUPP); -#endif #ifdef DEBUG if (args->flags & CLONE_PID) printf("linux_clone(%d): CLONE_PID not yet supported\n", p->p_pid); diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 822375dad9d0..88340e6626b6 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.35 1999/04/10 19:19:02 tegge Exp $ + * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ */ @@ -58,10 +58,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL,%eax ; \ + movl %ax,%fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ pushl _intr_unit + (irq_num) * 4 ; \ GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -74,6 +77,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -92,10 +96,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL, %eax ; \ movl %ax, %ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -113,6 +120,7 @@ IDTVEC(vec_name) ; \ 1: ; \ MEXITCOUNT ; \ REL_FAST_INTR_LOCK ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -130,6 +138,7 @@ IDTVEC(vec_name) ; \ lock ; \ incb _intr_nesting_level ; /* ... really limit it ... */ \ sti ; /* to do this as early as possible */ \ + popl %fs ; /* discard most of thin frame ... */ \ MAYBE_POPL_ES ; /* discard most of thin frame ... */ \ popl %ecx ; /* ... original %ds ... */ \ popl %edx ; \ @@ -137,11 +146,14 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; movl $KDSEL, %eax ; \ movl %ax, %es ; \ - movl (2+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ - movl %ecx, (2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ + movl $KPSEL, %eax ; + movl %ax, %fs ; + movl (3+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ + movl %ecx, (3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4, %esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -158,9 +170,11 @@ IDTVEC(vec_name) ; \ pushl $0 ; /* dummy trap type */ \ pushal ; \ pushl %ds ; /* save data and extra segments ... */ \ - pushl %es + pushl %es ; \ + pushl %fs #define POP_FRAME \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ @@ -319,6 +333,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -344,7 +360,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -429,6 +445,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -453,7 +471,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -549,8 +567,11 @@ _Xinvltlb: pushl %eax #ifdef COUNT_XINVLTLB_HITS - ss + pushl %fs + movl $KPSEL, %eax + movl %ax, %fs movl _cpuid, %eax + popl %fs ss incl _xhits(,%eax,4) #endif /* COUNT_XINVLTLB_HITS */ @@ -576,7 +597,7 @@ _Xinvltlb: * * - Signals its receipt by setting bit cpuid in checkstate_probed_cpus. * - * stack: 0 -> ds, 4 -> ebx, 8 -> eax, 12 -> eip, 16 -> cs, 20 -> eflags + * stack: 0->ds, 4->fs, 8->ebx, 12->eax, 16->eip, 20->cs, 24->eflags */ .text @@ -589,19 +610,22 @@ _Xcpucheckstate: pushl %eax pushl %ebx pushl %ds /* save current data segment */ + pushl %fs movl $KDSEL, %eax movl %ax, %ds /* use KERNEL data segment */ + movl $KPSEL, %eax + movl %ax, %fs movl $0, lapic_eoi /* End Of Interrupt to APIC */ movl $0, %ebx - movl 16(%esp), %eax + movl 20(%esp), %eax andl $3, %eax cmpl $3, %eax je 1f #ifdef VM86 - testl $PSL_VM, 20(%esp) + testl $PSL_VM, 24(%esp) jne 1f #endif incl %ebx /* system or interrupt */ @@ -615,12 +639,13 @@ _Xcpucheckstate: movl %ebx, _checkstate_cpustate(,%eax,4) movl _curproc, %ebx movl %ebx, _checkstate_curproc(,%eax,4) - movl 12(%esp), %ebx + movl 16(%esp), %ebx movl %ebx, _checkstate_pc(,%eax,4) lock /* checkstate_probed_cpus |= (1<tf_esi = ddb_regs.tf_esi; regs->tf_edi = ddb_regs.tf_edi; regs->tf_es = ddb_regs.tf_es & 0xffff; + regs->tf_fs = ddb_regs.tf_fs & 0xffff; regs->tf_cs = ddb_regs.tf_cs & 0xffff; regs->tf_ds = ddb_regs.tf_ds & 0xffff; return (1); diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c index 2ad054f2c4f8..6a361a0052f9 100644 --- a/sys/i386/i386/db_trace.c +++ b/sys/i386/i386/db_trace.c @@ -23,7 +23,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: db_trace.c,v 1.32 1999/01/27 23:45:38 dillon Exp $ + * $Id: db_trace.c,v 1.33 1999/01/28 01:59:50 dillon Exp $ */ #include @@ -47,8 +47,8 @@ struct db_variable db_regs[] = { { "cs", &ddb_regs.tf_cs, FCN_NULL }, { "ds", &ddb_regs.tf_ds, FCN_NULL }, { "es", &ddb_regs.tf_es, FCN_NULL }, -#if 0 { "fs", &ddb_regs.tf_fs, FCN_NULL }, +#if 0 { "gs", &ddb_regs.tf_gs, FCN_NULL }, #endif { "ss", &ddb_regs.tf_ss, FCN_NULL }, diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index a9286faf95e2..b87a1262dbdf 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $ + * $Id: exception.s,v 1.58 1999/04/16 21:22:12 peter Exp $ */ #include "npx.h" @@ -59,10 +59,12 @@ #define AVCPL_UNLOCK #endif /* SMP */ -#define KCSEL 0x08 /* kernel code selector */ -#define KDSEL 0x10 /* kernel data selector */ +#ifdef SMP +#define MOVL_KPSEL_EAX movl $KPSEL,%eax +#else +#define MOVL_KPSEL_EAX +#endif #define SEL_RPL_MASK 0x0003 -#define TRAPF_CS_OFF (13 * 4) .text @@ -149,10 +151,13 @@ IDTVEC(fpu) pushal pushl %ds pushl %es /* now stack frame is a trap frame */ + pushl %fs movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) #ifdef SMP MPLOCKED incl _cnt+V_TRAP @@ -198,11 +203,14 @@ _alltraps: pushal pushl %ds pushl %es + pushl %fs alltraps_with_regs_pushed: movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - FAKE_MCOUNT(12*4(%esp)) + MOVL_KPSEL_EAX + movl %ax,%fs + FAKE_MCOUNT(13*4(%esp)) calltrap: FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */ MPLOCKED incl _cnt+V_TRAP @@ -249,13 +257,16 @@ IDTVEC(syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */ movl %eax,TF_EFLAGS(%esp) movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL SYSCALL_LOCK ECPL_LOCK @@ -285,11 +296,14 @@ IDTVEC(int0x80_syscall) pushal pushl %ds pushl %es + pushl %fs movl $KDSEL,%eax /* switch to kernel segments */ movl %ax,%ds movl %ax,%es + MOVL_KPSEL_EAX + movl %ax,%fs movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */ - FAKE_MCOUNT(12*4(%esp)) + FAKE_MCOUNT(13*4(%esp)) MPLOCKED incl _cnt+V_SYSCALL ALTSYSCALL_LOCK ECPL_LOCK @@ -316,7 +330,9 @@ ENTRY(fork_trampoline) #ifdef SMP cmpl $0,_switchtime jne 1f - pushl $_switchtime + movl $gd_switchtime,%eax + addl %fs:0,%eax + pushl %eax call _microuptime popl %edx movl _ticks,%eax diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 539f3e2c7db0..3525455c8ebf 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 - * $Id: genassym.c,v 1.64 1999/02/28 10:53:28 bde Exp $ + * $Id: genassym.c,v 1.65 1999/04/02 17:59:37 alc Exp $ */ #include "opt_vm86.h" @@ -66,9 +66,7 @@ #ifdef SMP #include #endif -#ifdef VM86 #include -#endif #include #define OS(s, m) ((u_int)offsetof(struct s, m)) @@ -126,7 +124,6 @@ main() printf("#define\tPCB_EIP %#x\n", OS(pcb, pcb_eip)); printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0)); printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt)); - printf("#define\tPCB_FS %#x\n", OS(pcb, pcb_fs)); printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs)); #ifdef VM86 printf("#define\tPCB_EXT %#x\n", OS(pcb, pcb_ext)); @@ -134,6 +131,7 @@ main() #ifdef SMP printf("#define\tPCB_MPNEST %#x\n", OS(pcb, pcb_mpnest)); #endif + printf("#define\tPCB_SPARE %#x\n", OS(pcb, __pcb_spare)); printf("#define\tU_PROF %#x\n", OS(user, u_stats.p_prof)); printf("#define\tU_PROFSCALE %#x\n", OS(user, u_stats.p_prof.pr_scale)); @@ -194,42 +192,43 @@ main() printf("#define\tBI_MODULEP %#x\n", OS(bootinfo, bi_modulep)); printf("#define\tGD_SIZEOF %u\n", sizeof(struct globaldata)); - printf("#define\tGD_CURPROC %#x\n", OS(globaldata, curproc)); - printf("#define\tGD_NPXPROC %#x\n", OS(globaldata, npxproc)); - printf("#define\tGD_CURPCB %#x\n", OS(globaldata, curpcb)); - printf("#define\tGD_COMMON_TSS %#x\n", OS(globaldata, common_tss)); - printf("#define\tGD_SWITCHTIME %#x\n", OS(globaldata, switchtime)); - printf("#define\tGD_SWITCHTICKS %#x\n", OS(globaldata, switchticks)); + printf("#define\tGD_CURPROC %#x\n", OS(globaldata, gd_curproc)); + printf("#define\tGD_NPXPROC %#x\n", OS(globaldata, gd_npxproc)); + printf("#define\tGD_CURPCB %#x\n", OS(globaldata, gd_curpcb)); + printf("#define\tGD_COMMON_TSS %#x\n", OS(globaldata, gd_common_tss)); + printf("#define\tGD_SWITCHTIME %#x\n", OS(globaldata, gd_switchtime)); + printf("#define\tGD_SWITCHTICKS %#x\n", OS(globaldata, gd_switchticks)); #ifdef VM86 - printf("#define\tGD_COMMON_TSSD %#x\n", OS(globaldata, common_tssd)); - printf("#define\tGD_PRIVATE_TSS %#x\n", OS(globaldata, private_tss)); - printf("#define\tGD_MY_TR %#x\n", OS(globaldata, my_tr)); + printf("#define\tGD_COMMON_TSSD %#x\n", OS(globaldata, gd_common_tssd)); #endif #ifdef USER_LDT - printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, currentldt)); + printf("#define\tGD_CURRENTLDT %#x\n", OS(globaldata, gd_currentldt)); #endif #ifdef SMP - printf("#define\tGD_CPUID %#x\n", OS(globaldata, cpuid)); - printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, cpu_lockid)); - printf("#define\tGD_OTHER_CPUS %#x\n", OS(globaldata, other_cpus)); - printf("#define\tGD_MY_IDLEPTD %#x\n", OS(globaldata, my_idlePTD)); - printf("#define\tGD_SS_EFLAGS %#x\n", OS(globaldata, ss_eflags)); - printf("#define\tGD_PRV_CMAP1 %#x\n", OS(globaldata, prv_CMAP1)); - printf("#define\tGD_PRV_CMAP2 %#x\n", OS(globaldata, prv_CMAP2)); - printf("#define\tGD_PRV_CMAP3 %#x\n", OS(globaldata, prv_CMAP3)); - printf("#define\tGD_PRV_PMAP1 %#x\n", OS(globaldata, prv_PMAP1)); - printf("#define\tGD_INSIDE_INTR %#x\n", OS(globaldata, inside_intr)); + printf("#define\tGD_CPUID %#x\n", OS(globaldata, gd_cpuid)); + printf("#define\tGD_CPU_LOCKID %#x\n", OS(globaldata, gd_cpu_lockid)); + printf("#define\tGD_OTHER_CPUS %#x\n", OS(globaldata, gd_other_cpus)); + printf("#define\tGD_SS_EFLAGS %#x\n", OS(globaldata, gd_ss_eflags)); + printf("#define\tGD_INSIDE_INTR %#x\n", OS(globaldata, gd_inside_intr)); + printf("#define\tGD_PRV_CMAP1 %#x\n", OS(globaldata, gd_prv_CMAP1)); + printf("#define\tGD_PRV_CMAP2 %#x\n", OS(globaldata, gd_prv_CMAP2)); + printf("#define\tGD_PRV_CMAP3 %#x\n", OS(globaldata, gd_prv_CMAP3)); + printf("#define\tGD_PRV_PMAP1 %#x\n", OS(globaldata, gd_prv_PMAP1)); + printf("#define\tGD_PRV_CADDR1 %#x\n", OS(globaldata, gd_prv_CADDR1)); + printf("#define\tGD_PRV_CADDR2 %#x\n", OS(globaldata, gd_prv_CADDR2)); + printf("#define\tGD_PRV_CADDR3 %#x\n", OS(globaldata, gd_prv_CADDR3)); + printf("#define\tGD_PRV_PADDR1 %#x\n", OS(globaldata, gd_prv_PADDR1)); printf("#define\tPS_GLOBALDATA %#x\n", OS(privatespace, globaldata)); - printf("#define\tPS_PRVPT %#x\n", OS(privatespace, prvpt)); - printf("#define\tPS_LAPIC %#x\n", OS(privatespace, lapic)); printf("#define\tPS_IDLESTACK %#x\n", OS(privatespace, idlestack)); - printf("#define\tPS_IDLESTACK_TOP %#x\n", OS(privatespace, CPAGE1)); - printf("#define\tPS_CPAGE1 %#x\n", OS(privatespace, CPAGE1)); - printf("#define\tPS_CPAGE2 %#x\n", OS(privatespace, CPAGE2)); - printf("#define\tPS_CPAGE3 %#x\n", OS(privatespace, CPAGE3)); - printf("#define\tPS_PPAGE1 %#x\n", OS(privatespace, PPAGE1)); - printf("#define\tPS_IOAPICS %#x\n", OS(privatespace, ioapics)); + printf("#define\tPS_IDLESTACK_TOP %#x\n", sizeof(struct privatespace)); #endif + printf("#define\tKCSEL %#x\n", GSEL(GCODE_SEL, SEL_KPL)); + printf("#define\tKDSEL %#x\n", GSEL(GDATA_SEL, SEL_KPL)); +#ifdef SMP + printf("#define\tKPSEL %#x\n", GSEL(GPRIV_SEL, SEL_KPL)); +#endif + printf("#define\tGPROC0_SEL %#x\n", GPROC0_SEL); + return (0); } diff --git a/sys/i386/i386/globals.s b/sys/i386/i386/globals.s index 1697750e283f..92811d560666 100644 --- a/sys/i386/i386/globals.s +++ b/sys/i386/i386/globals.s @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globals.s,v 1.8 1998/09/28 12:20:46 peter Exp $ + * $Id: globals.s,v 1.9 1999/02/22 15:13:34 bde Exp $ */ #include "opt_vm86.h" @@ -40,36 +40,50 @@ * This is "constructed" in locore.s on the BSP and in mp_machdep.c * for each AP. DO NOT REORDER THESE WITHOUT UPDATING THE REST! */ - .globl _SMP_prvstart - .set _SMP_prvstart,(MPPTDI << PDRSHIFT) + .globl _SMP_prvspace, _lapic + .set _SMP_prvspace,(MPPTDI << PDRSHIFT) + .set _lapic,_SMP_prvspace + (NPTEPG-1) * PAGE_SIZE - .globl globaldata,_SMP_prvpt,_lapic,_SMP_ioapic - .globl _prv_CPAGE1,_prv_CPAGE2,_prv_CPAGE3,_prv_PPAGE1 - .globl _idlestack,_idlestack_top - - .set globaldata,_SMP_prvstart + PS_GLOBALDATA - .set _SMP_prvpt,_SMP_prvstart + PS_PRVPT - .set _lapic,_SMP_prvstart + PS_LAPIC - .set _idlestack,_SMP_prvstart + PS_IDLESTACK - .set _idlestack_top,_SMP_prvstart + PS_IDLESTACK_TOP - .set _prv_CPAGE1,_SMP_prvstart + PS_CPAGE1 - .set _prv_CPAGE2,_SMP_prvstart + PS_CPAGE2 - .set _prv_CPAGE3,_SMP_prvstart + PS_CPAGE3 - .set _prv_PPAGE1,_SMP_prvstart + PS_PPAGE1 - .set _SMP_ioapic,_SMP_prvstart + PS_IOAPICS + .globl gd_idlestack,gd_idlestack_top + .set gd_idlestack,PS_IDLESTACK + .set gd_idlestack_top,PS_IDLESTACK_TOP #endif /* * Define layout of the global data. On SMP this lives in * the per-cpu address space, otherwise it's in the data segment. */ + .globl globaldata #ifndef SMP .data ALIGN_DATA globaldata: .space GD_SIZEOF /* in data segment */ +#else + .set globaldata,0 #endif - .globl _curproc,_curpcb,_npxproc,_common_tss,_switchtime,_switchticks + .globl gd_curproc, gd_curpcb, gd_npxproc + .globl gd_common_tss, gd_switchtime, gd_switchticks + .set gd_curproc,globaldata + GD_CURPROC + .set gd_curpcb,globaldata + GD_CURPCB + .set gd_npxproc,globaldata + GD_NPXPROC + .set gd_common_tss,globaldata + GD_COMMON_TSS + .set gd_switchtime,globaldata + GD_SWITCHTIME + .set gd_switchticks,globaldata + GD_SWITCHTICKS + +#ifdef VM86 + .globl gd_common_tssd + .set gd_common_tssd,globaldata + GD_COMMON_TSSD +#endif + +#ifdef USER_LDT + .globl gd_currentldt + .set gd_currentldt,globaldata + GD_CURRENTLDT +#endif + +#ifndef SMP + .globl _curproc, _curpcb, _npxproc + .globl _common_tss, _switchtime, _switchticks .set _curproc,globaldata + GD_CURPROC .set _curpcb,globaldata + GD_CURPCB .set _npxproc,globaldata + GD_NPXPROC @@ -78,36 +92,39 @@ globaldata: .set _switchticks,globaldata + GD_SWITCHTICKS #ifdef VM86 - .globl _common_tssd,_private_tss,_my_tr + .globl _common_tssd .set _common_tssd,globaldata + GD_COMMON_TSSD - .set _private_tss,globaldata + GD_PRIVATE_TSS - .set _my_tr,globaldata + GD_MY_TR #endif #ifdef USER_LDT .globl _currentldt .set _currentldt,globaldata + GD_CURRENTLDT #endif +#endif #ifdef SMP /* * The BSP version of these get setup in locore.s and pmap.c, while * the AP versions are setup in mp_machdep.c. */ - .globl _cpuid,_cpu_lockid,_other_cpus,_my_idlePTD,_ss_eflags - .globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3,_prv_PMAP1 - .globl _inside_intr + .globl gd_cpuid, gd_cpu_lockid, gd_other_cpus + .globl gd_ss_eflags, gd_inside_intr + .globl gd_prv_CMAP1, gd_prv_CMAP2, gd_prv_CMAP3, gd_prv_PMAP1 + .globl gd_prv_CADDR1, gd_prv_CADDR2, gd_prv_CADDR3, gd_prv_PADDR1 - .set _cpuid,globaldata + GD_CPUID - .set _cpu_lockid,globaldata + GD_CPU_LOCKID - .set _other_cpus,globaldata + GD_OTHER_CPUS - .set _my_idlePTD,globaldata + GD_MY_IDLEPTD - .set _ss_eflags,globaldata + GD_SS_EFLAGS - .set _prv_CMAP1,globaldata + GD_PRV_CMAP1 - .set _prv_CMAP2,globaldata + GD_PRV_CMAP2 - .set _prv_CMAP3,globaldata + GD_PRV_CMAP3 - .set _prv_PMAP1,globaldata + GD_PRV_PMAP1 - .set _inside_intr,globaldata + GD_INSIDE_INTR + .set gd_cpuid,globaldata + GD_CPUID + .set gd_cpu_lockid,globaldata + GD_CPU_LOCKID + .set gd_other_cpus,globaldata + GD_OTHER_CPUS + .set gd_ss_eflags,globaldata + GD_SS_EFLAGS + .set gd_inside_intr,globaldata + GD_INSIDE_INTR + .set gd_prv_CMAP1,globaldata + GD_PRV_CMAP1 + .set gd_prv_CMAP2,globaldata + GD_PRV_CMAP2 + .set gd_prv_CMAP3,globaldata + GD_PRV_CMAP3 + .set gd_prv_PMAP1,globaldata + GD_PRV_PMAP1 + .set gd_prv_CADDR1,globaldata + GD_PRV_CADDR1 + .set gd_prv_CADDR2,globaldata + GD_PRV_CADDR2 + .set gd_prv_CADDR3,globaldata + GD_PRV_CADDR3 + .set gd_prv_PADDR1,globaldata + GD_PRV_PADDR1 #endif #if defined(SMP) || defined(APIC_IO) diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index 981418ba7ec0..63f74cc032ec 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.119 1999/01/30 15:38:47 kato Exp $ + * $Id: locore.s,v 1.120 1999/01/31 02:04:43 kato Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -102,7 +102,7 @@ HIDENAME(tmpstk): .globl _cpu,_cpu_vendor,_cpu_id,_bootinfo .globl _cpu_high, _cpu_feature -_cpu: .long 0 /* are we 386, 386sx, or 486 */ +_cpu: .long 0 /* are we 386, 386sx, or 486 */ _cpu_id: .long 0 /* stepping ID */ _cpu_high: .long 0 /* highest arg to CPUID */ _cpu_feature: .long 0 /* features */ @@ -113,12 +113,13 @@ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ #ifdef SMP + .globl _cpu0prvpage cpu0pp: .long 0 /* phys addr cpu0 private pg */ -cpu0pt: .long 0 /* phys addr cpu0 private pt */ - - .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ -_cpu0prvpt: .long 0 /* relocated version */ + + .globl _SMPpt +SMPptpa: .long 0 /* phys addr SMP page table */ +_SMPpt: .long 0 /* relocated version */ #endif /* SMP */ .globl _IdlePTD @@ -370,7 +371,6 @@ begin: movl _proc0paddr,%eax movl _IdlePTD, %esi movl %esi,PCB_CR3(%eax) - movl $_proc0,_curproc movl physfree, %esi pushl %esi /* value of first for init386(first) */ @@ -385,7 +385,7 @@ begin: pushl $PSL_USER /* eflags (IOPL 0, int enab) */ pushl __ucodesel /* cs */ pushl $0 /* eip - filled in by execve() */ - subl $(12*4),%esp /* space for rest of registers */ + subl $(13*4),%esp /* space for rest of registers */ pushl %esp /* call main with frame pointer */ call _main /* autoconfiguration, mountroot etc */ @@ -417,11 +417,11 @@ NON_GPROF_ENTRY(prepare_usermode) movl __ucodesel,%eax movl __udatasel,%ecx -#if 0 +#if 0 /* ds/es/fs are in trap frame */ movl %cx,%ds -#endif movl %cx,%es - movl %ax,%fs /* double map cs to fs */ + movl %cx,%fs +#endif movl %cx,%gs /* and ds to gs */ ret /* goto user! */ @@ -803,11 +803,11 @@ no_kernend: addl $KERNBASE, %esi movl %esi, R(_cpu0prvpage) /* relocated to KVM space */ -/* Allocate cpu0's private page table for mapping priv page, apic, etc */ +/* Allocate SMP page table page */ ALLOCPAGES(1) - movl %esi,R(cpu0pt) + movl %esi,R(SMPptpa) addl $KERNBASE, %esi - movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ + movl %esi, R(_SMPpt) /* relocated to KVM space */ #endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ @@ -887,25 +887,19 @@ map_read_write: movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global kmem FWIW */ - movl R(cpu0pt), %eax +/* Map SMP page table page into global kmem FWIW */ + movl R(SMPptpa), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table into private space */ +/* Map the private page into the SMP page table */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ - fillkpt(R(cpu0pt), $PG_RW) - -/* Map the page table page into private space */ - movl R(cpu0pt), %eax - movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* ... and put the page table table in the pde. */ - movl R(cpu0pt), %eax + movl R(SMPptpa), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) @@ -913,21 +907,12 @@ map_read_write: /* Fakeup VA for the local apic to allow early traps. */ ALLOCPAGES(1) movl %esi, %eax - movl $2, %ebx /* pte offset = 2 */ + movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */ movl $1, %ecx /* one private pt coming right up */ - fillkpt(R(cpu0pt), $PG_RW) + fillkpt(R(SMPptpa), $PG_RW) /* Initialize mp lock to allow early traps */ movl $1, R(_mp_lock) - -/* Initialize my_idlePTD to IdlePTD */ - movl R(cpu0pp), %eax - movl R(_IdlePTD), %ecx - movl %ecx,GD_MY_IDLEPTD(%eax) -/* Initialize IdlePTDS[0] */ - addl $KERNBASE, %ecx - movl %ecx, R(CNAME(IdlePTDS)) - #endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 712996e4c179..ac02b7abdbab 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.330 1999/04/19 14:14:12 peter Exp $ + * $Id: machdep.c,v 1.331 1999/04/26 08:57:51 peter Exp $ */ #include "apm.h" @@ -114,6 +114,7 @@ #include /* pcb.h included via sys/user.h */ #ifdef SMP #include +#include #endif #ifdef PERFMON #include @@ -552,6 +553,7 @@ sendsig(catcher, sig, mask, code) sf.sf_sc.sc_ds = regs->tf_ds; sf.sf_sc.sc_ss = regs->tf_ss; sf.sf_sc.sc_es = regs->tf_es; + sf.sf_sc.sc_fs = regs->tf_fs; sf.sf_sc.sc_isp = regs->tf_isp; /* @@ -616,6 +618,7 @@ sendsig(catcher, sig, mask, code) regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; } @@ -686,6 +689,7 @@ sigreturn(p, uap) tf->tf_vm86_gs = scp->sc_gs; tf->tf_ds = _udatasel; tf->tf_es = _udatasel; + tf->tf_fs = _udatasel; } else { #endif /* VM86 */ /* @@ -724,6 +728,7 @@ sigreturn(p, uap) } regs->tf_ds = scp->sc_ds; regs->tf_es = scp->sc_es; + regs->tf_fs = scp->sc_fs; #ifdef VM86 } #endif @@ -808,17 +813,16 @@ setregs(p, entry, stack, ps_strings) regs->tf_ss = _udatasel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_cs = _ucodesel; /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ regs->tf_ebx = ps_strings; - /* reset %fs and %gs as well */ - pcb->pcb_fs = _udatasel; + /* reset %gs as well */ pcb->pcb_gs = _udatasel; if (pcb == curpcb) { - __asm("movw %w0,%%fs" : : "r" (_udatasel)); - __asm("movw %w0,%%gs" : : "r" (_udatasel)); + load_gs(_udatasel); } /* @@ -887,7 +891,7 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, int _default_ldt; #ifdef SMP -union descriptor gdt[NGDT + NCPU]; /* global descriptor table */ +union descriptor gdt[NGDT * NCPU]; /* global descriptor table */ #else union descriptor gdt[NGDT]; /* global descriptor table */ #endif @@ -898,11 +902,11 @@ union descriptor ldt[NLDT]; /* local descriptor table */ struct region_descriptor r_gdt, r_idt; #endif -extern struct i386tss common_tss; /* One tss per cpu */ #ifdef VM86 +#ifndef SMP extern struct segment_descriptor common_tssd; -extern int private_tss; /* flag indicating private tss */ -extern u_int my_tr; /* which task register setting */ +#endif +int private_tss; /* flag indicating private tss */ #endif /* VM86 */ #if defined(I586_CPU) && !defined(NO_F00F_HACK) @@ -917,11 +921,7 @@ extern struct user *proc0paddr; /* software prototypes -- in more palatable form */ -struct soft_segment_descriptor gdt_segs[ -#ifdef SMP - NGDT + NCPU -#endif - ] = { +struct soft_segment_descriptor gdt_segs[] = { /* GNULL_SEL 0 Null Descriptor */ { 0x0, /* segment base address */ 0x0, /* length */ @@ -949,7 +949,26 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GLDT_SEL 3 LDT Descriptor */ +/* GPRIV_SEL 3 SMP Per-Processor Private Data Descriptor */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GPROC0_SEL 4 Proc 0 Tss Descriptor */ +{ + 0x0, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GLDT_SEL 5 LDT Descriptor */ { (int) ldt, /* segment base address */ sizeof(ldt)-1, /* length - all address space */ SDT_SYSLDT, /* segment type */ @@ -958,35 +977,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GTGATE_SEL 4 Null Descriptor - Placeholder */ -{ 0x0, /* segment base address */ - 0x0, /* length - all address space */ - 0, /* segment type */ - 0, /* segment descriptor priority level */ - 0, /* segment descriptor present */ - 0, 0, - 0, /* default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GPANIC_SEL 5 Panic Tss Descriptor */ -{ (int) &dblfault_tss, /* segment base address */ - sizeof(struct i386tss)-1,/* length - all address space */ - SDT_SYS386TSS, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ -{ - (int) &common_tss, /* segment base address */ - sizeof(struct i386tss)-1,/* length - all address space */ - SDT_SYS386TSS, /* segment type */ - 0, /* segment descriptor priority level */ - 1, /* segment descriptor present */ - 0, 0, - 0, /* unused - default 32 vs 16 bit size */ - 0 /* limit granularity (byte/page units)*/ }, -/* GUSERLDT_SEL 7 User LDT Descriptor per process */ +/* GUSERLDT_SEL 6 User LDT Descriptor per process */ { (int) ldt, /* segment base address */ (512 * sizeof(union descriptor)-1), /* length */ SDT_SYSLDT, /* segment type */ @@ -995,7 +986,25 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* unused - default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */ +/* GTGATE_SEL 7 Null Descriptor - Placeholder */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GPANIC_SEL 8 Panic Tss Descriptor */ +{ (int) &dblfault_tss, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GAPMCODE32_SEL 9 APM BIOS 32-bit interface (32bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1004,7 +1013,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */ +/* GAPMCODE16_SEL 10 APM BIOS 32-bit interface (16bit Code) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMERA, /* segment type */ @@ -1013,7 +1022,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, -/* GAPMDATA_SEL 10 APM BIOS 32-bit interface (Data) */ +/* GAPMDATA_SEL 11 APM BIOS 32-bit interface (Data) */ { 0, /* segment base address (overwritten by APM) */ 0xfffff, /* length */ SDT_MEMRWA, /* segment type */ @@ -1159,11 +1168,6 @@ init386(first) atdevbase = ISA_HOLE_START + KERNBASE; - /* - * Initialize the console before we print anything out. - */ - cninit(); - /* * make gdt memory segments, the code segment goes up to end of the * page with etext in it, the data segment goes to the end of @@ -1175,28 +1179,31 @@ init386(first) */ gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1; gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; -#ifdef BDE_DEBUGGER -#define NGDT1 8 /* avoid overwriting db entries with APM ones */ -#else -#define NGDT1 (sizeof gdt_segs / sizeof gdt_segs[0]) -#endif - for (x = 0; x < NGDT1; x++) - ssdtosd(&gdt_segs[x], &gdt[x].sd); -#ifdef VM86 - common_tssd = gdt[GPROC0_SEL].sd; -#endif /* VM86 */ - #ifdef SMP - /* - * Spin these up now. init_secondary() grabs them. We could use - * #for(x,y,z) / #endfor cpp directives if they existed. - */ - for (x = 0; x < NCPU; x++) { - gdt_segs[NGDT + x] = gdt_segs[GPROC0_SEL]; - ssdtosd(&gdt_segs[NGDT + x], &gdt[NGDT + x].sd); - } + gdt_segs[GPRIV_SEL].ssd_limit = + i386_btop(sizeof(struct privatespace)) - 1; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[0].globaldata.gd_common_tss; + SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0]; +#else + gdt_segs[GPRIV_SEL].ssd_limit = i386_btop(0) - 1; + gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss; #endif + for (x = 0; x < NGDT; x++) { +#ifdef BDE_DEBUGGER + /* avoid overwriting db entries with APM ones */ + if (x >= GAPMCODE32_SEL && x <= GAPMDATA_SEL) + continue; +#endif + ssdtosd(&gdt_segs[x], &gdt[x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) gdt; + lgdt(&r_gdt); + /* make ldt memory segments */ /* * The data segment limit must not cover the user area because we @@ -1221,6 +1228,12 @@ init386(first) for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) ssdtosd(&ldt_segs[x], &ldt[x].sd); + _default_ldt = GSEL(GLDT_SEL, SEL_KPL); + lldt(_default_ldt); +#ifdef USER_LDT + currentldt = _default_ldt; +#endif + /* exceptions */ for (x = 0; x < NIDT; x++) setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); @@ -1246,26 +1259,21 @@ init386(first) setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + r_idt.rd_limit = sizeof(idt) - 1; + r_idt.rd_base = (int) idt; + lidt(&r_idt); + + /* + * Initialize the console before we print anything out. + */ + cninit(); + #include "isa.h" #if NISA >0 isa_defaultirq(); #endif rand_initialize(); - r_gdt.rd_limit = sizeof(gdt) - 1; - r_gdt.rd_base = (int) gdt; - lgdt(&r_gdt); - - r_idt.rd_limit = sizeof(idt) - 1; - r_idt.rd_base = (int) idt; - lidt(&r_idt); - - _default_ldt = GSEL(GLDT_SEL, SEL_KPL); - lldt(_default_ldt); -#ifdef USER_LDT - currentldt = _default_ldt; -#endif - #ifdef DDB kdb_init(); if (boothowto & RB_KDB) @@ -1289,7 +1297,7 @@ init386(first) ltr(gsel_tss); #ifdef VM86 private_tss = 0; - my_tr = GPROC0_SEL; + common_tssd = gdt[GPROC0_SEL].sd; #endif dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = @@ -1607,6 +1615,7 @@ init386(first) #ifdef VM86 proc0.p_addr->u_pcb.pcb_ext = 0; #endif + SET_CURPROC(&proc0); /* Sigh, relocate physical addresses left from bootstrap */ if (bootinfo.bi_modulep) { @@ -1732,6 +1741,7 @@ fill_regs(p, regs) struct trapframe *tp; tp = p->p_md.md_regs; + regs->r_fs = tp->tf_fs; regs->r_es = tp->tf_es; regs->r_ds = tp->tf_ds; regs->r_edi = tp->tf_edi; @@ -1747,7 +1757,6 @@ fill_regs(p, regs) regs->r_esp = tp->tf_esp; regs->r_ss = tp->tf_ss; pcb = &p->p_addr->u_pcb; - regs->r_fs = pcb->pcb_fs; regs->r_gs = pcb->pcb_gs; return (0); } @@ -1764,6 +1773,7 @@ set_regs(p, regs) if (!EFLAGS_SECURE(regs->r_eflags, tp->tf_eflags) || !CS_SECURE(regs->r_cs)) return (EINVAL); + tp->tf_fs = regs->r_fs; tp->tf_es = regs->r_es; tp->tf_ds = regs->r_ds; tp->tf_edi = regs->r_edi; @@ -1779,7 +1789,6 @@ set_regs(p, regs) tp->tf_esp = regs->r_esp; tp->tf_ss = regs->r_ss; pcb = &p->p_addr->u_pcb; - pcb->pcb_fs = regs->r_fs; pcb->pcb_gs = regs->r_gs; return (0); } diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index eca2601a70b2..dcca437e8a10 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s index 7a5d431b65d0..8be76d7002c5 100644 --- a/sys/i386/i386/mpboot.s +++ b/sys/i386/i386/mpboot.s @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.8 1998/10/10 10:36:12 kato Exp $ + * $Id: mpboot.s,v 1.9 1999/04/10 22:58:29 tegge Exp $ */ #include "opt_vm86.h" @@ -76,12 +76,12 @@ NON_GPROF_ENTRY(MPentry) CHECKPOINT(0x36, 3) /* Now enable paging mode */ - movl _bootPTD-KERNBASE, %eax + movl _IdlePTD-KERNBASE, %eax movl %eax,%cr3 movl %cr0,%eax orl $CR0_PE|CR0_PG,%eax /* enable paging */ movl %eax,%cr0 /* let the games begin! */ - movl $_idlestack_top,%esp /* boot stack end loc. */ + movl _bootSTK,%esp /* boot stack end loc. */ pushl $mp_begin /* jump to high mem */ ret diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index eca2601a70b2..dcca437e8a10 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index bca25cc4a1ad..7aa92dedaa75 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.232 1999/04/23 20:29:58 dt Exp $ + * $Id: pmap.c,v 1.233 1999/04/25 18:40:05 alc Exp $ */ /* @@ -71,6 +71,8 @@ #include "opt_disable_pse.h" #include "opt_pmap.h" #include "opt_msgbuf.h" +#include "opt_vm86.h" +#include "opt_user_ldt.h" #include #include @@ -100,6 +102,9 @@ #if defined(SMP) || defined(APIC_IO) #include #include +#include +#include +#include #endif /* SMP || APIC_IO */ #define PMAP_KEEP_PDIRS @@ -146,7 +151,6 @@ static int protection_codes[8]; static struct pmap kernel_pmap_store; pmap_t kernel_pmap; -extern pd_entry_t my_idlePTD; vm_offset_t avail_start; /* PA of first available physical page */ vm_offset_t avail_end; /* PA of last available physical page */ @@ -184,19 +188,8 @@ static caddr_t CADDR2; static pt_entry_t *msgbufmap; struct msgbuf *msgbufp=0; -/* AIO support */ -extern struct vmspace *aiovmspace; - #ifdef SMP -extern char prv_CPAGE1[], prv_CPAGE2[], prv_CPAGE3[]; -extern pt_entry_t *prv_CMAP1, *prv_CMAP2, *prv_CMAP3; -extern pd_entry_t *IdlePTDS[]; -extern pt_entry_t SMP_prvpt[]; -#endif - -#ifdef SMP -extern unsigned int prv_PPAGE1[]; -extern pt_entry_t *prv_PMAP1; +extern pt_entry_t *SMPpt; #else static pt_entry_t *PMAP1 = 0; static unsigned *PADDR1 = 0; @@ -294,6 +287,7 @@ pmap_bootstrap(firstaddr, loadaddr) pt_entry_t *pte; #ifdef SMP int i, j; + struct globaldata *gd; #endif avail_start = firstaddr; @@ -404,12 +398,17 @@ pmap_bootstrap(firstaddr, loadaddr) ptditmp &= ~(NBPDR - 1); ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag; pdir4mb = ptditmp; + +#if !defined(SMP) /* * We can do the mapping here for the single processor * case. We simply ignore the old page table page from * now on. */ -#if !defined(SMP) + /* + * For SMP, we still need 4K pages to bootstrap APs, + * PSE will be enabled as soon as all APs are up. + */ PTD[KPTDI] = (pd_entry_t) ptditmp; kernel_pmap->pm_pdir[KPTDI] = (pd_entry_t) ptditmp; invltlb(); @@ -421,44 +420,46 @@ pmap_bootstrap(firstaddr, loadaddr) if (cpu_apic_address == 0) panic("pmap_bootstrap: no local apic!"); - /* 0 = private page */ - /* 1 = page table page */ - /* 2 = local apic */ - /* 16-31 = io apics */ - SMP_prvpt[2] = (pt_entry_t)(PG_V | PG_RW | pgeflag | + /* local apic is mapped on last page */ + SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag | (cpu_apic_address & PG_FRAME)); for (i = 0; i < mp_napics; i++) { - for (j = 0; j < 16; j++) { + for (j = 0; j < mp_napics; j++) { /* same page frame as a previous IO apic? */ - if (((vm_offset_t)SMP_prvpt[j + 16] & PG_FRAME) == + if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == (io_apic_address[0] & PG_FRAME)) { - ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace + + (NPTEPG-2-j)*PAGE_SIZE); break; } /* use this slot if available */ - if (((vm_offset_t)SMP_prvpt[j + 16] & PG_FRAME) == 0) { - SMP_prvpt[j + 16] = (pt_entry_t)(PG_V | PG_RW | + if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == 0) { + SMPpt[NPTEPG-2-j] = (pt_entry_t)(PG_V | PG_RW | pgeflag | (io_apic_address[i] & PG_FRAME)); - ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace + + (NPTEPG-2-j)*PAGE_SIZE); break; } } - if (j == 16) - panic("no space to map IO apic %d!", i); } /* BSP does this itself, AP's get it pre-set */ - prv_CMAP1 = &SMP_prvpt[3 + UPAGES]; - prv_CMAP2 = &SMP_prvpt[4 + UPAGES]; - prv_CMAP3 = &SMP_prvpt[5 + UPAGES]; - prv_PMAP1 = &SMP_prvpt[6 + UPAGES]; + gd = &SMP_prvspace[0].globaldata; + gd->gd_prv_CMAP1 = &SMPpt[1]; + gd->gd_prv_CMAP2 = &SMPpt[2]; + gd->gd_prv_CMAP3 = &SMPpt[3]; + gd->gd_prv_PMAP1 = &SMPpt[4]; + gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[0].PPAGE1; #endif invltlb(); - } +#ifdef SMP /* * Set 4mb pdir for mp startup, and global flags */ @@ -493,6 +494,7 @@ pmap_set_opt_bsp(void) pmap_set_opt((unsigned *)PTD); invltlb(); } +#endif /* * Initialize the pmap module. @@ -716,9 +718,9 @@ pmap_pte_quick(pmap, va) #ifdef SMP if ( ((* (unsigned *) prv_PMAP1) & PG_FRAME) != newpf) { * (unsigned *) prv_PMAP1 = newpf | PG_RW | PG_V; - cpu_invlpg(&prv_PPAGE1); + cpu_invlpg(prv_PADDR1); } - return prv_PPAGE1 + ((unsigned) index & (NPTEPG - 1)); + return prv_PADDR1 + ((unsigned) index & (NPTEPG - 1)); #else if ( ((* (unsigned *) PMAP1) & PG_FRAME) != newpf) { * (unsigned *) PMAP1 = newpf | PG_RW | PG_V; @@ -1122,7 +1124,6 @@ pmap_unuse_pt(pmap, va, mpte) return pmap_unwire_pte_hold(pmap, mpte); } -#if !defined(SMP) void pmap_pinit0(pmap) struct pmap *pmap; @@ -1136,14 +1137,6 @@ pmap_pinit0(pmap) TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); } -#else -void -pmap_pinit0(pmap) - struct pmap *pmap; -{ - pmap_pinit(pmap); -} -#endif /* * Initialize a preallocated and zeroed pmap structure, @@ -1189,6 +1182,9 @@ pmap_pinit(pmap) /* wire in kernel global address entries */ /* XXX copies current process, does not fill in MPPTDI */ bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE); +#ifdef SMP + pmap->pm_pdir[MPPTDI] = PTD[MPPTDI]; +#endif /* install self-referential address mapping entry */ *(unsigned *) (pmap->pm_pdir + PTDPTDI) = @@ -1430,9 +1426,6 @@ pmap_growkernel(vm_offset_t addr) int s; vm_offset_t ptppaddr; vm_page_t nkpg; -#ifdef SMP - int i; -#endif pd_entry_t newpdir; s = splhigh(); @@ -1468,23 +1461,12 @@ pmap_growkernel(vm_offset_t addr) newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M); pdir_pde(PTD, kernel_vm_end) = newpdir; -#ifdef SMP - for (i = 0; i < mp_ncpus; i++) { - if (IdlePTDS[i]) - pdir_pde(IdlePTDS[i], kernel_vm_end) = newpdir; - } -#endif - for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { if (p->p_vmspace) { pmap = vmspace_pmap(p->p_vmspace); *pmap_pde(pmap, kernel_vm_end) = newpdir; } } - if (aiovmspace != NULL) { - pmap = vmspace_pmap(aiovmspace); - *pmap_pde(pmap, kernel_vm_end) = newpdir; - } *pmap_pde(kernel_pmap, kernel_vm_end) = newpdir; kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); } @@ -2739,14 +2721,14 @@ pmap_zero_page(phys) #endif *(int *) prv_CMAP3 = PG_V | PG_RW | (phys & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE3); + cpu_invlpg(prv_CADDR3); #if defined(I686_CPU) if (cpu_class == CPUCLASS_686) - i686_pagezero(&prv_CPAGE3); + i686_pagezero(prv_CADDR3); else #endif - bzero(&prv_CPAGE3, PAGE_SIZE); + bzero(prv_CADDR3, PAGE_SIZE); *(int *) prv_CMAP3 = 0; #else @@ -2787,14 +2769,14 @@ pmap_zero_page_area(phys, off, size) #endif *(int *) prv_CMAP3 = PG_V | PG_RW | (phys & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE3); + cpu_invlpg(prv_CADDR3); #if defined(I686_CPU) if (cpu_class == CPUCLASS_686 && off == 0 && size == PAGE_SIZE) - i686_pagezero(&prv_CPAGE3); + i686_pagezero(prv_CADDR3); else #endif - bzero((char *)&prv_CPAGE3 + off, size); + bzero((char *)prv_CADDR3 + off, size); *(int *) prv_CMAP3 = 0; #else @@ -2838,10 +2820,10 @@ pmap_copy_page(src, dst) *(int *) prv_CMAP1 = PG_V | (src & PG_FRAME) | PG_A; *(int *) prv_CMAP2 = PG_V | PG_RW | (dst & PG_FRAME) | PG_A | PG_M; - cpu_invlpg(&prv_CPAGE1); - cpu_invlpg(&prv_CPAGE2); + cpu_invlpg(prv_CADDR1); + cpu_invlpg(prv_CADDR2); - bcopy(&prv_CPAGE1, &prv_CPAGE2, PAGE_SIZE); + bcopy(prv_CADDR1, prv_CADDR2, PAGE_SIZE); *(int *) prv_CMAP1 = 0; *(int *) prv_CMAP2 = 0; diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s index cb9fd3e37588..7093dbb86df4 100644 --- a/sys/i386/i386/support.s +++ b/sys/i386/i386/support.s @@ -30,9 +30,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.61 1999/03/21 12:30:50 phk Exp $ + * $Id: support.s,v 1.62 1999/03/30 09:00:40 phk Exp $ */ +#include "opt_smp.h" #include "npx.h" #include @@ -42,8 +43,6 @@ #include "assym.s" -#define KDSEL 0x10 /* kernel data selector */ -#define KCSEL 0x8 /* kernel code selector */ #define IDXSHIFT 10 .data @@ -1495,9 +1494,12 @@ ENTRY(lgdt) movl $KDSEL,%eax movl %ax,%ds movl %ax,%es - movl %ax,%fs movl %ax,%gs movl %ax,%ss +#ifdef SMP + movl $KPSEL,%eax +#endif + movl %ax,%fs /* reload code selector by turning return into intersegmental return */ movl (%esp),%eax diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index 7e97a09981c7..ae4ca62319ea 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.77 1999/03/20 18:44:13 alc Exp $ + * $Id: swtch.s,v 1.78 1999/04/02 17:59:39 alc Exp $ */ #include "npx.h" @@ -258,25 +258,32 @@ _idle: /* when called, we have the mplock, intr disabled */ /* use our idleproc's "context" */ - movl _my_idlePTD,%ecx - movl %ecx,%cr3 + movl _IdlePTD, %ecx + movl %cr3, %eax + cmpl %ecx, %eax + je 2f #if defined(SWTCH_OPTIM_STATS) + decl _swtch_optim_stats incl _tlb_flush_count #endif + movl %ecx, %cr3 +2: /* Keep space for nonexisting return addr, or profiling bombs */ - movl $_idlestack_top-4,%ecx - movl %ecx,%esp + movl $gd_idlestack_top-4, %ecx + addl %fs:0, %ecx + movl %ecx, %esp /* update common_tss.tss_esp0 pointer */ -#ifdef VM86 - movl _my_tr, %esi -#endif /* VM86 */ movl %ecx, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 1f - movl $_common_tssd, %edi + movl _cpuid, %esi + btrl %esi, _private_tss + jae 1f + + movl $GPROC0_SEL, %esi + movl $gd_common_tssd, %edi + addl %fs:0, %edi /* move correct tss descriptor into GDT slot, then reload tr */ leal _gdt(,%esi,8), %ebx /* entry in GDT */ @@ -388,14 +395,14 @@ idle_loop: #endif /* update common_tss.tss_esp0 pointer */ -#ifdef VM86 - movl _my_tr, %esi -#endif /* VM86 */ movl %esp, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 1f + movl $0, %esi + btrl %esi, _private_tss + jae 1f + + movl $GPROC0_SEL, %esi movl $_common_tssd, %edi /* move correct tss descriptor into GDT slot, then reload tr */ @@ -477,7 +484,6 @@ ENTRY(cpu_switch) movl %ebp,PCB_EBP(%edx) movl %esi,PCB_ESI(%edx) movl %edi,PCB_EDI(%edx) - movl %fs,PCB_FS(%edx) movl %gs,PCB_GS(%edx) #ifdef SMP @@ -610,70 +616,55 @@ swtch_com: movl %eax,P_BACK(%ecx) /* isolate process to run */ movl P_ADDR(%ecx),%edx -#ifdef SMP - movl PCB_CR3(%edx),%ebx - /* Grab the private PT pointer from the outgoing process's PTD */ - movl $_PTD, %esi - movl 4*MPPTDI(%esi), %eax /* fetch cpu's prv pt */ -#else #if defined(SWTCH_OPTIM_STATS) incl _swtch_optim_stats #endif /* switch address space */ movl %cr3,%ebx cmpl PCB_CR3(%edx),%ebx - je 4f + je 4f #if defined(SWTCH_OPTIM_STATS) decl _swtch_optim_stats incl _tlb_flush_count #endif movl PCB_CR3(%edx),%ebx -#endif /* SMP */ movl %ebx,%cr3 4: -#ifdef SMP - /* Copy the private PT to the new process's PTD */ - /* XXX yuck, the _PTD changes when we switch, so we have to - * reload %cr3 after changing the address space. - * We need to fix this by storing a pointer to the virtual - * location of the per-process PTD in the PCB or something quick. - * Dereferencing proc->vm_map->pmap->p_pdir[] is painful in asm. - */ - movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ - -#if defined(SWTCH_OPTIM_STATS) - incl _tlb_flush_count -#endif - /* XXX: we have just changed the page tables.. reload.. */ - movl %ebx, %cr3 -#endif /* SMP */ - #ifdef VM86 - movl _my_tr, %esi +#ifdef SMP + movl _cpuid, %esi +#else + xorl %esi, %esi +#endif cmpl $0, PCB_EXT(%edx) /* has pcb extension? */ je 1f - movl $1, _private_tss /* mark use of private tss */ + btsl %esi, _private_tss /* mark use of private tss */ movl PCB_EXT(%edx), %edi /* new tss descriptor */ jmp 2f 1: #endif /* update common_tss.tss_esp0 pointer */ - movl $_common_tss, %eax movl %edx, %ebx /* pcb */ #ifdef VM86 addl $(UPAGES * PAGE_SIZE - 16), %ebx #else addl $(UPAGES * PAGE_SIZE), %ebx #endif /* VM86 */ - movl %ebx, TSS_ESP0(%eax) + movl %ebx, _common_tss + TSS_ESP0 #ifdef VM86 - cmpl $0, _private_tss - je 3f + btrl %esi, _private_tss + jae 3f +#ifdef SMP + movl $gd_common_tssd, %edi + addl %fs:0, %edi +#else movl $_common_tssd, %edi +#endif 2: + movl $GPROC0_SEL, %esi /* move correct tss descriptor into GDT slot, then reload tr */ leal _gdt(,%esi,8), %ebx /* entry in GDT */ movl 0(%edi), %eax @@ -738,9 +729,6 @@ swtch_com: #endif /* This must be done after loading the user LDT. */ - .globl cpu_switch_load_fs -cpu_switch_load_fs: - movl PCB_FS(%edx),%fs .globl cpu_switch_load_gs cpu_switch_load_gs: movl PCB_GS(%edx),%gs @@ -791,7 +779,6 @@ ENTRY(savectx) movl %ebp,PCB_EBP(%ecx) movl %esi,PCB_ESI(%ecx) movl %edi,PCB_EDI(%ecx) - movl %fs,PCB_FS(%ecx) movl %gs,PCB_GS(%ecx) #if NNPX > 0 diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 9c3df3640565..4c40ed495898 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -31,12 +31,13 @@ * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.39 1999/01/28 01:59:50 dillon Exp $ + * $Id: sys_machdep.c,v 1.40 1999/04/27 11:14:33 phk Exp $ * */ #include "opt_user_ldt.h" #include "opt_vm86.h" +#include "opt_smp.h" #include #include @@ -54,6 +55,7 @@ #include #include /* pcb.h included by sys/user.h */ #include +#include #include /* for kernel_map */ @@ -261,7 +263,11 @@ set_user_ldt(struct pcb *pcb) { gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)pcb->pcb_ldt; gdt_segs[GUSERLDT_SEL].ssd_limit = (pcb->pcb_ldt_len * sizeof(union descriptor)) - 1; +#ifdef SMP + ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[cpuid * NGDT + GUSERLDT_SEL].sd); +#else ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[GUSERLDT_SEL].sd); +#endif lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); currentldt = GSEL(GUSERLDT_SEL, SEL_KPL); } diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index d08306e99ce8..c0807b0787a5 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.134 1999/03/09 20:20:09 phk Exp $ + * $Id: trap.c,v 1.135 1999/04/19 14:14:13 peter Exp $ */ /* @@ -101,8 +101,6 @@ #include "isa.h" #include "npx.h" -extern struct i386tss common_tss; - int (*pmath_emulate) __P((struct trapframe *)); extern void trap __P((struct trapframe frame)); @@ -480,11 +478,6 @@ kernel_trap: * (XXX) so that we can continue, and generate * a signal. */ - if (frame.tf_eip == (int)cpu_switch_load_fs) { - curpcb->pcb_fs = 0; - psignal(p, SIGBUS); - return; - } if (frame.tf_eip == (int)cpu_switch_load_gs) { curpcb->pcb_gs = 0; psignal(p, SIGBUS); @@ -496,6 +489,8 @@ kernel_trap: doreti_popl_ds_fault); MAYBE_DORETI_FAULT(doreti_popl_es, doreti_popl_es_fault); + MAYBE_DORETI_FAULT(doreti_popl_fs, + doreti_popl_fs_fault); if (curpcb && curpcb->pcb_onfault) { frame.tf_eip = (int)curpcb->pcb_onfault; return; diff --git a/sys/i386/i386/vm86.c b/sys/i386/i386/vm86.c index 30b085f9211d..96e4bf2f504a 100644 --- a/sys/i386/i386/vm86.c +++ b/sys/i386/i386/vm86.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: vm86.c,v 1.22 1999/03/18 04:37:18 jlemon Exp $ + * $Id: vm86.c,v 1.23 1999/03/18 18:43:03 jlemon Exp $ */ #include "opt_vm86.h" @@ -49,7 +49,9 @@ #include extern int i386_extend_pcb __P((struct proc *)); +#ifndef SMP extern struct segment_descriptor common_tssd; +#endif extern int vm86paddr, vm86pa; extern struct pcb *vm86pcb; @@ -411,8 +413,8 @@ vm86_initialize(void) * pcb_esp = stack frame pointer at time of switch * pcb_ebx = va of vm86 page table * pcb_eip = argument pointer to initial call - * pcb_fs = saved TSS descriptor, word 0 - * pcb_gs = saved TSS descriptor, word 1 + * pcb_spare[0] = saved TSS descriptor, word 0 + * pcb_space[1] = saved TSS descriptor, word 1 */ #define new_ptd pcb_esi #define vm86_frame pcb_ebp @@ -614,7 +616,7 @@ vm86_prepcall(struct vm86frame vmf) vmf.vmf_cs = 0; } vmf.vmf_sp = addr[1] - 2; /* keep aligned */ - vmf.kernel_es = vmf.kernel_ds = 0; + vmf.kernel_fs = vmf.kernel_es = vmf.kernel_ds = 0; vmf.vmf_ss = 0; vmf.vmf_eflags = PSL_VIF | PSL_VM | PSL_USER; vm86_initflags(&vmf); diff --git a/sys/i386/i386/vm86bios.s b/sys/i386/i386/vm86bios.s index 3a1d4b30585d..c772e546f17c 100644 --- a/sys/i386/i386/vm86bios.s +++ b/sys/i386/i386/vm86bios.s @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: vm86bios.s,v 1.7 1998/10/01 20:45:28 jlemon Exp $ + * $Id: vm86bios.s,v 1.8 1999/03/18 04:37:19 jlemon Exp $ */ #include "opt_vm86.h" @@ -38,8 +38,8 @@ #define SCR_STACK PCB_ESP #define SCR_PGTABLE PCB_EBX #define SCR_ARGFRAME PCB_EIP -#define SCR_TSS0 PCB_FS -#define SCR_TSS1 PCB_GS +#define SCR_TSS0 PCB_SPARE +#define SCR_TSS1 (PCB_SPARE+4) .data ALIGN_DATA @@ -62,7 +62,6 @@ ENTRY(vm86_bioscall) pushl %ebp pushl %esi pushl %edi - pushl %fs pushl %gs #ifdef SMP @@ -99,7 +98,7 @@ ENTRY(vm86_bioscall) pushl %eax /* save curpcb */ movl %edx,_curpcb /* set curpcb to vm86pcb */ - movl _my_tr,%esi + movl $GPROC0_SEL,%esi leal _gdt(,%esi,8),%ebx /* entry in GDT */ movl 0(%ebx),%eax movl %eax,SCR_TSS0(%edx) /* save first word */ @@ -117,15 +116,9 @@ ENTRY(vm86_bioscall) movl %cr3,%eax pushl %eax /* save address space */ -#ifdef SMP - movl _cpuid, %ecx - movl CNAME(IdlePTDS)(,%ecx,4), %ebx - movl _my_idlePTD,%ecx -#else movl _IdlePTD,%ecx movl %ecx,%ebx addl $KERNBASE,%ebx /* va of Idle PTD */ -#endif movl 0(%ebx),%eax pushl %eax /* old ptde != 0 when booting */ pushl %ebx /* keep for reuse */ @@ -183,7 +176,7 @@ ENTRY(vm86_biosret) movl $0,_in_vm86call /* reset trapflag */ - movl _my_tr,%esi + movl $GPROC0_SEL,%esi leal _gdt(,%esi,8),%ebx /* entry in GDT */ movl SCR_TSS0(%edx),%eax movl %eax,0(%ebx) /* restore first word */ @@ -197,7 +190,6 @@ ENTRY(vm86_biosret) movl TF_TRAPNO(%edx),%eax /* return (trapno) */ popl %gs - popl %fs popl %edi popl %esi popl %ebp diff --git a/sys/i386/include/asnames.h b/sys/i386/include/asnames.h index 8ac432c53c89..0cc77d6ca3c9 100644 --- a/sys/i386/include/asnames.h +++ b/sys/i386/include/asnames.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: asnames.h,v 1.30 1999/02/25 12:53:34 bde Exp $ + * $Id: asnames.h,v 1.31 1999/04/16 21:22:16 peter Exp $ */ #ifndef _MACHINE_ASNAMES_H_ @@ -65,8 +65,8 @@ #define _PTD PTD #define _PTDpde PTDpde #define _PTmap PTmap -#define _SMP_ioapic SMP_ioapic -#define _SMP_prvpt SMP_prvpt +#define _SMP_prvspace SMP_prvspace +#define _SMPpt SMPpt #define _Xalign Xalign #define _Xbnd Xbnd #define _Xbpt Xbpt @@ -181,7 +181,7 @@ #define _bootDataSeg bootDataSeg #define _bootMP bootMP #define _bootMP_size bootMP_size -#define _bootPTD bootPTD +#define _bootSTK bootSTK #define _boot_get_mplock boot_get_mplock #define _bootdev bootdev #define _boothowto boothowto @@ -198,15 +198,12 @@ #define _checkstate_probed_cpus checkstate_probed_cpus #define _clock_lock clock_lock #define _cnt cnt -#define _common_tss common_tss -#define _common_tssd common_tssd #define _copyin_vector copyin_vector #define _copyout_vector copyout_vector #define _cpl cpl #define _cpl_lock cpl_lock #define _cpu cpu #define _cpu0prvpage cpu0prvpage -#define _cpu0prvpt cpu0prvpt #define _cpu_apic_versions cpu_apic_versions #define _cpu_class cpu_class #define _cpu_feature cpu_feature @@ -215,10 +212,6 @@ #define _cpu_num_to_apic_id cpu_num_to_apic_id #define _cpu_switch cpu_switch #define _cpu_vendor cpu_vendor -#define _cpuid cpuid -#define _curpcb curpcb -#define _curproc curproc -#define _currentldt currentldt #define _cypoll cypoll #define _default_halt default_halt #define _denormal_operand denormal_operand @@ -245,7 +238,7 @@ #define _get_isrlock get_isrlock #define _get_mplock get_mplock #define _get_syscall_lock get_syscall_lock -#define _getmicrouptime getmicrouptime +#define _getmicrouptime getmicrouptime #define _idqs idqs #define _ihandlers ihandlers #define _imen imen @@ -254,7 +247,6 @@ #define _init386 init386 #define _init_secondary init_secondary #define _initial_bioscalls initial_bioscalls -#define _inside_intr inside_intr #define _intr_countp intr_countp #define _intr_handler intr_handler #define _intr_mask intr_mask @@ -280,8 +272,6 @@ #define _mp_lock mp_lock #define _mp_ncpus mp_ncpus #define _mul64 mul64 -#define _my_idlePTD my_idlePTD -#define _my_tr my_tr #define _net_imask net_imask #define _netisr netisr #define _netisrs netisrs @@ -292,9 +282,7 @@ #define _npx_intrs_while_probing npx_intrs_while_probing #define _npx_traps_while_probing npx_traps_while_probing #define _npx_intr npx_intr -#define _npxproc npxproc #define _npxsave npxsave -#define _other_cpus other_cpus #define _ovbcopy_vector ovbcopy_vector #define _panic panic #define _pc98_system_parameter pc98_system_parameter @@ -307,14 +295,6 @@ #define _probetrap probetrap #define _proc0 proc0 #define _proc0paddr proc0paddr -#define _prv_CMAP1 prv_CMAP1 -#define _prv_CMAP2 prv_CMAP2 -#define _prv_CMAP3 prv_CMAP3 -#define _prv_CPAGE1 prv_CPAGE1 -#define _prv_CPAGE2 prv_CPAGE2 -#define _prv_CPAGE3 prv_CPAGE3 -#define _prv_PMAP1 prv_PMAP1 -#define _prv_PPAGE1 prv_PPAGE1 #define _qs qs #define _rcpoll rcpoll #define _real_2op_NaN real_2op_NaN @@ -354,8 +334,6 @@ #define _swi_generic swi_generic #define _swi_null swi_null #define _swi_vm swi_vm -#define _switchticks switchticks -#define _switchtime switchtime #define _syscall syscall #define _szsigcode szsigcode #define _ticks ticks @@ -390,4 +368,37 @@ #endif /* __ELF__ */ +#if defined(SMP) || defined(__ELF__) +#ifdef SMP +#define FS(x) %fs:gd_ ## x +#else +#define FS(x) x +#endif + +#define _common_tss FS(common_tss) +#define _common_tssd FS(common_tssd) +#define _cpuid FS(cpuid) +#define _cpu_lockid FS(cpu_lockid) +#define _curpcb FS(curpcb) +#define _curproc FS(curproc) +#define _currentldt FS(currentldt) +#define _inside_intr FS(inside_intr) +#define _npxproc FS(npxproc) +#define _other_cpus FS(other_cpus) +#define _prv_CADDR1 FS(prv_CADDR1) +#define _prv_CADDR2 FS(prv_CADDR2) +#define _prv_CADDR3 FS(prv_CADDR3) +#define _prv_CMAP1 FS(prv_CMAP1) +#define _prv_CMAP2 FS(prv_CMAP2) +#define _prv_CMAP3 FS(prv_CMAP3) +#define _prv_PADDR1 FS(prv_PADDR1) +#define _prv_PMAP1 FS(prv_PMAP1) +#define _ss_eflags FS(ss_eflags) +#define _switchticks FS(switchticks) +#define _switchtime FS(switchtime) +#define _idlestack FS(idlestack) +#define _idlestack_top FS(idlestack_top) + +#endif + #endif /* !_MACHINE_ASNAMES_H_ */ diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index ce6bf0589001..c1f9f17c8487 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.84 1999/01/08 19:51:02 bde Exp $ + * $Id: cpufunc.h,v 1.85 1999/01/09 13:00:27 bde Exp $ */ /* @@ -426,6 +426,34 @@ wrmsr(u_int msr, u_int64_t newval) __asm __volatile(".byte 0x0f, 0x30" : : "A" (newval), "c" (msr)); } +static __inline u_int +rfs(void) +{ + u_int sel; + __asm __volatile("movl %%fs,%0" : "=r" (sel)); + return (sel); +} + +static __inline u_int +rgs(void) +{ + u_int sel; + __asm __volatile("movl %%gs,%0" : "=r" (sel)); + return (sel); +} + +static __inline void +load_fs(u_int sel) +{ + __asm __volatile("movl %0,%%fs" : : "r" (sel)); +} + +static __inline void +load_gs(u_int sel) +{ + __asm __volatile("movl %0,%%gs" : : "r" (sel)); +} + #else /* !__GNUC__ */ int breakpoint __P((void)); @@ -456,6 +484,10 @@ void setbits __P((volatile u_int *addr, u_int bits)); void wbinvd __P((void)); void write_eflags __P((u_int ef)); void wrmsr __P((u_int msr, u_int64_t newval)); +u_int rfs __P((void)); +u_int rgs __P((void)); +void load_fs __P((u_int sel)); +void load_gs __P((u_int sel)); #endif /* __GNUC__ */ diff --git a/sys/i386/include/frame.h b/sys/i386/include/frame.h index 05092c2c4c07..7d70c14dff64 100644 --- a/sys/i386/include/frame.h +++ b/sys/i386/include/frame.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)frame.h 5.2 (Berkeley) 1/18/91 - * $Id: frame.h,v 1.14 1997/02/22 09:34:38 peter Exp $ + * $Id: frame.h,v 1.15 1997/08/09 00:03:12 dyson Exp $ */ #ifndef _MACHINE_FRAME_H_ @@ -51,6 +51,7 @@ */ struct trapframe { + int tf_fs; int tf_es; int tf_ds; int tf_edi; @@ -75,6 +76,7 @@ struct trapframe { /* Superset of trap frame, for traps from virtual-8086 mode */ struct trapframe_vm86 { + int tf_fs; int tf_es; int tf_ds; int tf_edi; @@ -106,6 +108,7 @@ struct trapframe_vm86 { struct intrframe { int if_vec; int if_ppl; + int if_fs; int if_es; int if_ds; int if_edi; @@ -132,6 +135,7 @@ struct intrframe { struct clockframe { int cf_vec; int cf_ppl; + int cf_fs; int cf_es; int cf_ds; int cf_edi; diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h index ec5879940ecd..f1d4fdd0ffa1 100644 --- a/sys/i386/include/globaldata.h +++ b/sys/i386/include/globaldata.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.6 1998/08/18 07:47:12 msmith Exp $ + * $Id: globaldata.h,v 1.7 1999/02/22 15:13:34 bde Exp $ */ /* @@ -39,31 +39,33 @@ * other processors" */ struct globaldata { - struct proc *curproc; - struct proc *npxproc; - struct pcb *curpcb; - struct i386tss common_tss; - struct timeval switchtime; - int switchticks; + struct privatespace *gd_prvspace; /* self-reference */ + struct proc *gd_curproc; + struct proc *gd_npxproc; + struct pcb *gd_curpcb; + struct timeval gd_switchtime; + struct i386tss gd_common_tss; + int gd_switchticks; #ifdef VM86 - struct segment_descriptor common_tssd; - u_int private_tss; - u_int my_tr; + struct segment_descriptor gd_common_tssd; #endif #ifdef USER_LDT - int currentldt; + int gd_currentldt; #endif #ifdef SMP - u_int cpuid; - u_int cpu_lockid; - u_int other_cpus; - pd_entry_t *my_idlePTD; - u_int ss_eflags; - pt_entry_t *prv_CMAP1; - pt_entry_t *prv_CMAP2; - pt_entry_t *prv_CMAP3; - pt_entry_t *prv_PMAP1; - int inside_intr; + u_int gd_cpuid; + u_int gd_cpu_lockid; + u_int gd_other_cpus; + int gd_inside_intr; + u_int gd_ss_eflags; + pt_entry_t *gd_prv_CMAP1; + pt_entry_t *gd_prv_CMAP2; + pt_entry_t *gd_prv_CMAP3; + pt_entry_t *gd_prv_PMAP1; + caddr_t gd_prv_CADDR1; + caddr_t gd_prv_CADDR2; + caddr_t gd_prv_CADDR3; + unsigned *gd_prv_PADDR1; #endif }; @@ -78,28 +80,16 @@ struct privatespace { struct globaldata globaldata; char __filler0[PAGE_SIZE - sizeof(struct globaldata)]; - /* page 1 - page table page */ - pt_entry_t prvpt[NPTEPG]; - - /* page 2 - local apic mapping */ - lapic_t lapic; - char __filler1[PAGE_SIZE - sizeof(lapic_t)]; - - /* page 3..2+UPAGES - idle stack (UPAGES pages) */ - char idlestack[UPAGES * PAGE_SIZE]; - - /* page 3+UPAGES..6+UPAGES - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ + /* page 1..4 - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ char CPAGE1[PAGE_SIZE]; char CPAGE2[PAGE_SIZE]; char CPAGE3[PAGE_SIZE]; char PPAGE1[PAGE_SIZE]; - /* page 7+UPAGES..15 - spare, unmapped */ - char __filler2[(9-UPAGES) * PAGE_SIZE]; - - /* page 16-31 - space for IO apics */ - char ioapics[16 * PAGE_SIZE]; - - /* page 32-47 - maybe other cpu's globaldata pages? */ + /* page 5..4+UPAGES - idle stack (UPAGES pages) */ + char idlestack[UPAGES * PAGE_SIZE]; }; + +extern struct privatespace SMP_prvspace[]; + #endif diff --git a/sys/i386/include/globals.h b/sys/i386/include/globals.h new file mode 100644 index 000000000000..5a770f16f078 --- /dev/null +++ b/sys/i386/include/globals.h @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 1999 Luoqi Chen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _MACHINE_GLOBALS_H_ +#define _MACHINE_GLOBALS_H_ + +#ifdef KERNEL + +#define GLOBAL_LVALUE(name, type) \ + (*(type *)_global_ptr_##name()) + +#define GLOBAL_RVALUE(name, type) \ + ((type)_global_##name()) + +/* non-volatile version */ +#define GLOBAL_LVALUE_NV(name, type) \ + (*(type *)_global_ptr_##name##_nv()) + +#define GLOBAL_RVALUE_NV(name, type) \ + ((type)_global_##name##_nv()) + +#define GLOBAL_FUNC(name) \ + static __inline void *_global_ptr_##name(void) { \ + void *val; \ + __asm __volatile("movl $gd_" #name ",%0;" \ + "addl %%fs:globaldata,%0" : "=r" (val)); \ + return (val); \ + } \ + static __inline void *_global_ptr_##name##_nv(void) { \ + void *val; \ + __asm("movl $gd_" #name ",%0;" \ + "addl %%fs:globaldata,%0" : "=r" (val)); \ + return (val); \ + } \ + static __inline int _global_##name(void) { \ + int val; \ + __asm __volatile("movl %%fs:gd_" #name ",%0" : "=r" (val)); \ + return (val); \ + } \ + static __inline int _global_##name##_nv(void) { \ + int val; \ + __asm("movl %%fs:gd_" #name ",%0" : "=r" (val)); \ + return (val); \ + } \ + static __inline void _global_##name##_set(int val) { \ + __asm __volatile("movl %0,%%fs:gd_" #name : : "r" (val)); \ + } \ + static __inline void _global_##name##_set_nv(int val) { \ + __asm("movl %0,%%fs:gd_" #name : : "r" (val)); \ + } + +#if defined(SMP) || defined(KLD_MODULE) || defined(ACTUALLY_LKM_NOT_KERNEL) +/* + * The following set of macros works for UP kernel as well, but for maximum + * performance we allow the global variables to be accessed directly. On the + * other hand, kernel modules should always use these macros to maintain + * portability between UP and SMP kernels. + */ +#define curproc GLOBAL_RVALUE_NV(curproc, struct proc *) +#define curpcb GLOBAL_RVALUE_NV(curpcb, struct pcb *) +#define npxproc GLOBAL_LVALUE(npxproc, struct proc *) +#define common_tss GLOBAL_LVALUE(common_tss, struct i386tss) +#define switchtime GLOBAL_LVALUE(switchtime, struct timeval) +#define switchticks GLOBAL_LVALUE(switchticks, int) + +#ifdef VM86 +#define common_tssd GLOBAL_LVALUE(common_tssd, struct segment_descriptor) +#endif + +#ifdef USER_LDT +#define currentldt GLOBAL_LVALUE(currentldt, int) +#endif + +#ifdef SMP +#define cpuid GLOBAL_RVALUE(cpuid, u_int) +#define other_cpus GLOBAL_LVALUE(other_cpus, u_int) +#define inside_intr GLOBAL_LVALUE(inside_intr, int) +#define prv_CMAP1 GLOBAL_LVALUE(prv_CMAP1, pt_entry_t *) +#define prv_CMAP2 GLOBAL_LVALUE(prv_CMAP2, pt_entry_t *) +#define prv_CMAP3 GLOBAL_LVALUE(prv_CMAP3, pt_entry_t *) +#define prv_PMAP1 GLOBAL_LVALUE(prv_PMAP1, pt_entry_t *) +#define prv_CADDR1 GLOBAL_RVALUE(prv_CADDR1, caddr_t) +#define prv_CADDR2 GLOBAL_RVALUE(prv_CADDR2, caddr_t) +#define prv_CADDR3 GLOBAL_RVALUE(prv_CADDR3, caddr_t) +#define prv_PADDR1 GLOBAL_RVALUE(prv_PADDR1, unsigned *) +#endif +#endif /*UP kernel*/ + +GLOBAL_FUNC(curproc) +GLOBAL_FUNC(curpcb) +GLOBAL_FUNC(npxproc) +GLOBAL_FUNC(common_tss) +GLOBAL_FUNC(switchtime) +GLOBAL_FUNC(switchticks) + +#ifdef VM86 +GLOBAL_FUNC(common_tssd) +#endif + +#ifdef USER_LDT +GLOBAL_FUNC(currentldt) +#endif + +#ifdef SMP +GLOBAL_FUNC(cpuid) +GLOBAL_FUNC(other_cpus) +GLOBAL_FUNC(inside_intr) +GLOBAL_FUNC(prv_CMAP1) +GLOBAL_FUNC(prv_CMAP2) +GLOBAL_FUNC(prv_CMAP3) +GLOBAL_FUNC(prv_PMAP1) +GLOBAL_FUNC(prv_CADDR1) +GLOBAL_FUNC(prv_CADDR2) +GLOBAL_FUNC(prv_CADDR3) +GLOBAL_FUNC(prv_PADDR1) +#endif + +#define SET_CURPROC(x) (_global_curproc_set_nv((int)x)) + +#endif /* KERNEL */ + +#endif /* !_MACHINE_GLOBALS_H_ */ diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index fd7bcfd2c661..35b65455e244 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: md_var.h,v 1.27 1998/10/30 05:41:15 msmith Exp $ + * $Id: md_var.h,v 1.28 1999/01/08 16:29:58 bde Exp $ */ #ifndef _MACHINE_MD_VAR_H_ @@ -69,7 +69,6 @@ void bcopyb __P((const void *from, void *to, size_t len)); void busdma_swi __P((void)); void cpu_halt __P((void)); void cpu_reset __P((void)); -void cpu_switch_load_fs __P((void)) __asm(__STRING(cpu_switch_load_fs)); void cpu_switch_load_gs __P((void)) __asm(__STRING(cpu_switch_load_gs)); void doreti_iret __P((void)) __asm(__STRING(doreti_iret)); void doreti_iret_fault __P((void)) __asm(__STRING(doreti_iret_fault)); @@ -77,6 +76,8 @@ void doreti_popl_ds __P((void)) __asm(__STRING(doreti_popl_ds)); void doreti_popl_ds_fault __P((void)) __asm(__STRING(doreti_popl_ds_fault)); void doreti_popl_es __P((void)) __asm(__STRING(doreti_popl_es)); void doreti_popl_es_fault __P((void)) __asm(__STRING(doreti_popl_es_fault)); +void doreti_popl_fs __P((void)) __asm(__STRING(doreti_popl_fs)); +void doreti_popl_fs_fault __P((void)) __asm(__STRING(doreti_popl_fs_fault)); int fill_fpregs __P((struct proc *, struct fpreg *)); int fill_regs __P((struct proc *p, struct reg *regs)); void fillw __P((int /*u_short*/ pat, void *base, size_t cnt)); diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index eca2601a70b2..dcca437e8a10 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h index a7608d5f7add..10384c6ebf9b 100644 --- a/sys/i386/include/npx.h +++ b/sys/i386/include/npx.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id: npx.h,v 1.13 1997/06/22 16:03:50 peter Exp $ + * $Id: npx.h,v 1.14 1997/07/20 11:06:44 bde Exp $ */ /* @@ -45,6 +45,8 @@ #ifndef _MACHINE_NPX_H_ #define _MACHINE_NPX_H_ +#include + /* Environment information of floating point unit */ struct env87 { long en_cw; /* control word (16bits) */ @@ -135,7 +137,9 @@ struct save87 { #endif #ifdef KERNEL +#ifndef npxproc extern struct proc *npxproc; +#endif int npxdna __P((void)); void npxexit __P((struct proc *p)); diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h index d76217ff3b8e..9ab0856137a7 100644 --- a/sys/i386/include/pcb.h +++ b/sys/i386/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.25 1997/10/10 12:40:09 peter Exp $ + * $Id: pcb.h,v 1.26 1998/02/03 21:27:50 bde Exp $ */ #ifndef _I386_PCB_H_ @@ -43,6 +43,7 @@ /* * Intel 386 process control block */ +#include #include struct pcb { @@ -64,14 +65,13 @@ struct pcb { #else u_long pcb_mpnest_dontuse; #endif - int pcb_fs; int pcb_gs; #ifdef VM86 struct pcb_ext *pcb_ext; /* optional pcb extension */ #else struct pcb_ext *pcb_ext_dontuse; #endif - u_long __pcb_spare[1]; /* adjust to avoid core dump size changes */ + u_long __pcb_spare[2]; /* adjust to avoid core dump size changes */ }; /* @@ -83,7 +83,9 @@ struct md_coredump { #ifdef KERNEL +#ifndef curpcb extern struct pcb *curpcb; /* our current running pcb */ +#endif void savectx __P((struct pcb *)); #endif diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index ec5879940ecd..f1d4fdd0ffa1 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: globaldata.h,v 1.6 1998/08/18 07:47:12 msmith Exp $ + * $Id: globaldata.h,v 1.7 1999/02/22 15:13:34 bde Exp $ */ /* @@ -39,31 +39,33 @@ * other processors" */ struct globaldata { - struct proc *curproc; - struct proc *npxproc; - struct pcb *curpcb; - struct i386tss common_tss; - struct timeval switchtime; - int switchticks; + struct privatespace *gd_prvspace; /* self-reference */ + struct proc *gd_curproc; + struct proc *gd_npxproc; + struct pcb *gd_curpcb; + struct timeval gd_switchtime; + struct i386tss gd_common_tss; + int gd_switchticks; #ifdef VM86 - struct segment_descriptor common_tssd; - u_int private_tss; - u_int my_tr; + struct segment_descriptor gd_common_tssd; #endif #ifdef USER_LDT - int currentldt; + int gd_currentldt; #endif #ifdef SMP - u_int cpuid; - u_int cpu_lockid; - u_int other_cpus; - pd_entry_t *my_idlePTD; - u_int ss_eflags; - pt_entry_t *prv_CMAP1; - pt_entry_t *prv_CMAP2; - pt_entry_t *prv_CMAP3; - pt_entry_t *prv_PMAP1; - int inside_intr; + u_int gd_cpuid; + u_int gd_cpu_lockid; + u_int gd_other_cpus; + int gd_inside_intr; + u_int gd_ss_eflags; + pt_entry_t *gd_prv_CMAP1; + pt_entry_t *gd_prv_CMAP2; + pt_entry_t *gd_prv_CMAP3; + pt_entry_t *gd_prv_PMAP1; + caddr_t gd_prv_CADDR1; + caddr_t gd_prv_CADDR2; + caddr_t gd_prv_CADDR3; + unsigned *gd_prv_PADDR1; #endif }; @@ -78,28 +80,16 @@ struct privatespace { struct globaldata globaldata; char __filler0[PAGE_SIZE - sizeof(struct globaldata)]; - /* page 1 - page table page */ - pt_entry_t prvpt[NPTEPG]; - - /* page 2 - local apic mapping */ - lapic_t lapic; - char __filler1[PAGE_SIZE - sizeof(lapic_t)]; - - /* page 3..2+UPAGES - idle stack (UPAGES pages) */ - char idlestack[UPAGES * PAGE_SIZE]; - - /* page 3+UPAGES..6+UPAGES - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ + /* page 1..4 - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ char CPAGE1[PAGE_SIZE]; char CPAGE2[PAGE_SIZE]; char CPAGE3[PAGE_SIZE]; char PPAGE1[PAGE_SIZE]; - /* page 7+UPAGES..15 - spare, unmapped */ - char __filler2[(9-UPAGES) * PAGE_SIZE]; - - /* page 16-31 - space for IO apics */ - char ioapics[16 * PAGE_SIZE]; - - /* page 32-47 - maybe other cpu's globaldata pages? */ + /* page 5..4+UPAGES - idle stack (UPAGES pages) */ + char idlestack[UPAGES * PAGE_SIZE]; }; + +extern struct privatespace SMP_prvspace[]; + #endif diff --git a/sys/i386/include/proc.h b/sys/i386/include/proc.h index e7a4744a03b5..ae6cd6337bc3 100644 --- a/sys/i386/include/proc.h +++ b/sys/i386/include/proc.h @@ -31,12 +31,14 @@ * SUCH DAMAGE. * * from: @(#)proc.h 7.1 (Berkeley) 5/15/91 - * $Id: proc.h,v 1.7 1997/02/22 09:34:59 peter Exp $ + * $Id: proc.h,v 1.8 1997/05/07 19:55:13 peter Exp $ */ #ifndef _MACHINE_PROC_H_ #define _MACHINE_PROC_H_ +#include + /* * Machine-dependent part of the proc structure for i386. */ diff --git a/sys/i386/include/reg.h b/sys/i386/include/reg.h index 28466a838bc8..247011646fa5 100644 --- a/sys/i386/include/reg.h +++ b/sys/i386/include/reg.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)reg.h 5.5 (Berkeley) 1/18/91 - * $Id: reg.h,v 1.16 1998/09/14 22:43:40 jdp Exp $ + * $Id: reg.h,v 1.17 1999/04/03 22:19:59 jdp Exp $ */ #ifndef _MACHINE_REG_H_ @@ -51,22 +51,23 @@ * stopped accessing the registers in the trap frame via PT_{READ,WRITE}_U * and we can stop supporting the user area soon. */ -#define tES (0) -#define tDS (1) -#define tEDI (2) -#define tESI (3) -#define tEBP (4) -#define tISP (5) -#define tEBX (6) -#define tEDX (7) -#define tECX (8) -#define tEAX (9) -#define tERR (11) -#define tEIP (12) -#define tCS (13) -#define tEFLAGS (14) -#define tESP (15) -#define tSS (16) +#define tFS (0) +#define tES (1) +#define tDS (2) +#define tEDI (3) +#define tESI (4) +#define tEBP (5) +#define tISP (6) +#define tEBX (7) +#define tEDX (8) +#define tECX (9) +#define tEAX (10) +#define tERR (12) +#define tEIP (13) +#define tCS (14) +#define tEFLAGS (15) +#define tESP (16) +#define tSS (17) /* * Indices for registers in `struct regs' only. @@ -75,13 +76,13 @@ * other registers in application interfaces that copy all the registers * to or from a `struct regs'. */ -#define tFS (17) #define tGS (18) /* * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS. */ struct reg { + unsigned int r_fs; unsigned int r_es; unsigned int r_ds; unsigned int r_edi; @@ -99,7 +100,6 @@ struct reg { unsigned int r_eflags; unsigned int r_esp; unsigned int r_ss; - unsigned int r_fs; unsigned int r_gs; }; diff --git a/sys/i386/include/segments.h b/sys/i386/include/segments.h index 674b0f38c28e..eaecfa322c5f 100644 --- a/sys/i386/include/segments.h +++ b/sys/i386/include/segments.h @@ -35,12 +35,14 @@ * SUCH DAMAGE. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 - * $Id: segments.h,v 1.17 1997/08/21 06:32:49 charnier Exp $ + * $Id: segments.h,v 1.18 1999/01/28 11:45:49 newton Exp $ */ #ifndef _MACHINE_SEGMENTS_H_ #define _MACHINE_SEGMENTS_H_ +#include + /* * 386 Segmentation Data Structures and definitions * William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989 @@ -207,19 +209,20 @@ struct region_descriptor { #define GNULL_SEL 0 /* Null Descriptor */ #define GCODE_SEL 1 /* Kernel Code Descriptor */ #define GDATA_SEL 2 /* Kernel Data Descriptor */ -#define GLDT_SEL 3 /* LDT - eventually one per process */ -#define GTGATE_SEL 4 /* Process task switch gate */ -#define GPANIC_SEL 5 /* Task state to consider panic from */ -#define GPROC0_SEL 6 /* Task state process slot zero and up */ -#define GUSERLDT_SEL 7 /* User LDT */ -#define GAPMCODE32_SEL 8 /* APM BIOS 32-bit interface (32bit Code) */ -#define GAPMCODE16_SEL 9 /* APM BIOS 32-bit interface (16bit Code) */ -#define GAPMDATA_SEL 10 /* APM BIOS 32-bit interface (Data) */ +#define GPRIV_SEL 3 /* SMP Per-Processor Private Data */ +#define GPROC0_SEL 4 /* Task state process slot zero and up */ +#define GLDT_SEL 5 /* LDT - eventually one per process */ +#define GUSERLDT_SEL 6 /* User LDT */ +#define GTGATE_SEL 7 /* Process task switch gate */ +#define GPANIC_SEL 8 /* Task state to consider panic from */ +#define GAPMCODE32_SEL 9 /* APM BIOS 32-bit interface (32bit Code) */ +#define GAPMCODE16_SEL 10 /* APM BIOS 32-bit interface (16bit Code) */ +#define GAPMDATA_SEL 11 /* APM BIOS 32-bit interface (Data) */ #ifdef BDE_DEBUGGER #define NGDT 18 /* some of 11-17 are reserved for debugger */ #else -#define NGDT (GAPMDATA_SEL + 1) +#define NGDT 12 #endif /* @@ -237,7 +240,9 @@ struct region_descriptor { #define NLDT (LBSDICALLS_SEL + 1) #ifdef KERNEL +#ifndef currentldt extern int currentldt; +#endif extern int _default_ldt; extern union descriptor gdt[]; extern struct soft_segment_descriptor gdt_segs[]; diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 0f4f915366b6..3750c72011eb 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ + * $Id: smp.h,v 1.44 1998/09/06 22:41:40 tegge Exp $ * */ @@ -112,7 +112,6 @@ struct apic_intmapinfo { }; extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; -extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; /* functions in mp_machdep.c */ @@ -175,12 +174,6 @@ extern int invltlb_ok; extern int smp_active; extern volatile int smp_idle_loops; -/* 'private' global data in locore.s */ -extern volatile u_int cpuid; -extern volatile u_int cpu_lockid; -extern int inside_intr; -extern volatile u_int other_cpus; - #endif /* !LOCORE */ #endif /* SMP || APIC_IO */ #endif /* KERNEL */ diff --git a/sys/i386/include/tss.h b/sys/i386/include/tss.h index 565defab8cb7..636133a9a870 100644 --- a/sys/i386/include/tss.h +++ b/sys/i386/include/tss.h @@ -34,12 +34,14 @@ * SUCH DAMAGE. * * from: @(#)tss.h 5.4 (Berkeley) 1/18/91 - * $Id$ + * $Id: tss.h,v 1.8 1997/02/22 09:35:20 peter Exp $ */ #ifndef _MACHINE_TSS_H_ #define _MACHINE_TSS_H_ 1 +#include + /* * Intel 386 Context Data Type */ @@ -79,4 +81,11 @@ struct i386tss { int tss_ioopt; /* options & io offset bitmap: currently zero */ /* XXX unimplemented .. i/o permission bitmap */ }; + +#ifdef KERNEL +#ifndef common_tss +extern struct i386tss common_tss; +#endif +#endif + #endif /* _MACHINE_TSS_H_ */ diff --git a/sys/i386/include/vm86.h b/sys/i386/include/vm86.h index 0862f49cf629..a7d565c29295 100644 --- a/sys/i386/include/vm86.h +++ b/sys/i386/include/vm86.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: vm86.h,v 1.8 1998/09/29 09:06:00 bde Exp $ + * $Id: vm86.h,v 1.9 1999/03/18 04:37:35 jlemon Exp $ */ #ifndef _MACHINE_VM86_H_ @@ -49,6 +49,7 @@ typedef union { /* layout must match definition of struct trapframe_vm86 in */ struct vm86frame { + int kernel_fs; int kernel_es; int kernel_ds; reg86_t edi; diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 822375dad9d0..88340e6626b6 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.35 1999/04/10 19:19:02 tegge Exp $ + * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ */ @@ -58,10 +58,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL,%eax ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL,%eax ; \ + movl %ax,%fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ pushl _intr_unit + (irq_num) * 4 ; \ GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -74,6 +77,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -92,10 +96,13 @@ IDTVEC(vec_name) ; \ pushl %edx ; \ pushl %ds ; \ MAYBE_PUSHL_ES ; \ + pushl %fs ; \ movl $KDSEL, %eax ; \ movl %ax, %ds ; \ MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ + FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ @@ -113,6 +120,7 @@ IDTVEC(vec_name) ; \ 1: ; \ MEXITCOUNT ; \ REL_FAST_INTR_LOCK ; \ + popl %fs ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ @@ -130,6 +138,7 @@ IDTVEC(vec_name) ; \ lock ; \ incb _intr_nesting_level ; /* ... really limit it ... */ \ sti ; /* to do this as early as possible */ \ + popl %fs ; /* discard most of thin frame ... */ \ MAYBE_POPL_ES ; /* discard most of thin frame ... */ \ popl %ecx ; /* ... original %ds ... */ \ popl %edx ; \ @@ -137,11 +146,14 @@ IDTVEC(vec_name) ; \ pushal ; /* build fat frame (grrr) ... */ \ pushl %ecx ; /* ... actually %ds ... */ \ pushl %es ; \ + pushl %fs ; movl $KDSEL, %eax ; \ movl %ax, %es ; \ - movl (2+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ - movl %ecx, (2+6)*4(%esp) ; /* ... to fat frame ... */ \ - movl (2+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ + movl $KPSEL, %eax ; + movl %ax, %fs ; + movl (3+8+0)*4(%esp), %ecx ; /* %ecx from thin frame ... */ \ + movl %ecx, (3+6)*4(%esp) ; /* ... to fat frame ... */ \ + movl (3+8+1)*4(%esp), %eax ; /* ... cpl from thin frame */ \ pushl %eax ; \ subl $4, %esp ; /* junk for unit number */ \ MEXITCOUNT ; \ @@ -158,9 +170,11 @@ IDTVEC(vec_name) ; \ pushl $0 ; /* dummy trap type */ \ pushal ; \ pushl %ds ; /* save data and extra segments ... */ \ - pushl %es + pushl %es ; \ + pushl %fs #define POP_FRAME \ + popl %fs ; \ popl %es ; \ popl %ds ; \ popal ; \ @@ -319,6 +333,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -344,7 +360,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -429,6 +445,8 @@ IDTVEC(vec_name) ; \ movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ movl %ax, %ds ; \ movl %ax, %es ; \ + movl $KPSEL, %eax ; \ + movl %ax, %fs ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -453,7 +471,7 @@ IDTVEC(vec_name) ; \ ; \ /* entry point used by doreti_unpend for HWIs. */ \ __CONCAT(Xresume,irq_num): ; \ - FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid dbl cnt */ \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ lock ; incl (%eax) ; \ @@ -549,8 +567,11 @@ _Xinvltlb: pushl %eax #ifdef COUNT_XINVLTLB_HITS - ss + pushl %fs + movl $KPSEL, %eax + movl %ax, %fs movl _cpuid, %eax + popl %fs ss incl _xhits(,%eax,4) #endif /* COUNT_XINVLTLB_HITS */ @@ -576,7 +597,7 @@ _Xinvltlb: * * - Signals its receipt by setting bit cpuid in checkstate_probed_cpus. * - * stack: 0 -> ds, 4 -> ebx, 8 -> eax, 12 -> eip, 16 -> cs, 20 -> eflags + * stack: 0->ds, 4->fs, 8->ebx, 12->eax, 16->eip, 20->cs, 24->eflags */ .text @@ -589,19 +610,22 @@ _Xcpucheckstate: pushl %eax pushl %ebx pushl %ds /* save current data segment */ + pushl %fs movl $KDSEL, %eax movl %ax, %ds /* use KERNEL data segment */ + movl $KPSEL, %eax + movl %ax, %fs movl $0, lapic_eoi /* End Of Interrupt to APIC */ movl $0, %ebx - movl 16(%esp), %eax + movl 20(%esp), %eax andl $3, %eax cmpl $3, %eax je 1f #ifdef VM86 - testl $PSL_VM, 20(%esp) + testl $PSL_VM, 24(%esp) jne 1f #endif incl %ebx /* system or interrupt */ @@ -615,12 +639,13 @@ _Xcpucheckstate: movl %ebx, _checkstate_cpustate(,%eax,4) movl _curproc, %ebx movl %ebx, _checkstate_curproc(,%eax,4) - movl 12(%esp), %ebx + movl 16(%esp), %ebx movl %ebx, _checkstate_pc(,%eax,4) lock /* checkstate_probed_cpus |= (1< #include #include +#include #ifndef SMP /* diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c index 76b8ced0eb66..99a88a510f6f 100644 --- a/sys/i386/linux/linux_genassym.c +++ b/sys/i386/linux/linux_genassym.c @@ -1,4 +1,4 @@ -/* $Id: linux_genassym.c,v 1.7 1998/02/01 18:47:56 bde Exp $ */ +/* $Id: linux_genassym.c,v 1.8 1998/07/29 15:50:41 bde Exp $ */ #include @@ -16,7 +16,6 @@ main() printf("#define\tLINUX_SIGF_HANDLER %u\n", OS(linux_sigframe, sf_handler)); printf("#define\tLINUX_SIGF_SC %u\n", OS(linux_sigframe, sf_sc)); - printf("#define\tLINUX_SC_FS %u\n", OS(linux_sigcontext, sc_fs)); printf("#define\tLINUX_SC_GS %u\n", OS(linux_sigcontext, sc_gs)); printf("#define\tLINUX_SC_EFLAGS %u\n", OS(linux_sigcontext, sc_eflags)); diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s index 1440218e847d..b458c94dac81 100644 --- a/sys/i386/linux/linux_locore.s +++ b/sys/i386/linux/linux_locore.s @@ -6,9 +6,7 @@ NON_GPROF_ENTRY(linux_sigcode) call LINUX_SIGF_HANDLER(%esp) leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */ - movl LINUX_SC_FS(%ebx),%ecx movl LINUX_SC_GS(%ebx),%edx - movl %cx,%fs movl %dx,%gs push %eax /* fake ret addr */ movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index 68a2d4308f7e..e01693ad0aef 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.55 1999/04/27 11:15:32 phk Exp $ + * $Id: linux_misc.c,v 1.56 1999/04/27 12:21:04 phk Exp $ */ #include @@ -531,18 +531,18 @@ select_out: int linux_getpgid(struct proc *p, struct linux_getpgid_args *args) { - struct proc *curproc; + struct proc *curp; #ifdef DEBUG printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); #endif if (args->pid != p->p_pid) { - if (!(curproc = pfind(args->pid))) + if (!(curp = pfind(args->pid))) return ESRCH; } else - curproc = p; - p->p_retval[0] = curproc->p_pgid; + curp = p; + p->p_retval[0] = curp->p_pgid; return 0; } @@ -576,10 +576,6 @@ linux_clone(struct proc *p, struct linux_clone_args *args) vm_offset_t start; struct rfork_args rf_args; -#ifdef SMP - printf("linux_clone(%d): does not work with SMP yet\n", p->p_pid); - return (EOPNOTSUPP); -#endif #ifdef DEBUG if (args->flags & CLONE_PID) printf("linux_clone(%d): CLONE_PID not yet supported\n", p->p_pid); diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index d3a2f714613e..8584d96c895d 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.45 1999/02/04 21:20:13 newton Exp $ + * $Id: linux_sysvec.c,v 1.46 1999/04/19 14:14:14 peter Exp $ */ /* XXX we use functions that might not exist. */ @@ -249,8 +249,8 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) * Build the signal context to be used by sigreturn. */ frame.sf_sc.sc_mask = mask; - __asm("movl %%gs,%w0" : "=r" (frame.sf_sc.sc_gs)); - __asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs)); + frame.sf_sc.sc_gs = rgs(); + frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; frame.sf_sc.sc_ds = regs->tf_ds; frame.sf_sc.sc_edi = regs->tf_edi; @@ -286,6 +286,7 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; } @@ -359,7 +360,8 @@ linux_sigreturn(p, args) /* * Restore signal context. */ - /* %fs and %gs were restored by the trampoline. */ + /* %gs was restored by the trampoline. */ + regs->tf_fs = context.sc_fs; regs->tf_es = context.sc_es; regs->tf_ds = context.sc_ds; regs->tf_edi = context.sc_edi; diff --git a/sys/i386/svr4/svr4_locore.s b/sys/i386/svr4/svr4_locore.s index 7903e736fa9d..2f9c683c23c1 100644 --- a/sys/i386/svr4/svr4_locore.s +++ b/sys/i386/svr4/svr4_locore.s @@ -13,11 +13,11 @@ NON_GPROF_ENTRY(svr4_sigcode) jnz 1f #endif #endif - movl SVR4_UC_FS(%eax),%ecx movl SVR4_UC_GS(%eax),%edx - movl %cx,%fs movl %dx,%gs #if defined(__NetBSD__) + movl SVR4_UC_FS(%eax),%ecx + movl %cx,%fs 1: pushl %eax pushl $1 # setcontext(p) == syscontext(1, p) pushl %eax # junk to fake return address diff --git a/sys/i386/svr4/svr4_machdep.c b/sys/i386/svr4/svr4_machdep.c index a94f45e78cf8..5e77fd1ada54 100644 --- a/sys/i386/svr4/svr4_machdep.c +++ b/sys/i386/svr4/svr4_machdep.c @@ -127,8 +127,13 @@ svr4_getcontext(p, uc, mask, oonstack) } else #endif { +#if defined(__NetBSD__) __asm("movl %%gs,%w0" : "=r" (r[SVR4_X86_GS])); __asm("movl %%fs,%w0" : "=r" (r[SVR4_X86_FS])); +#else + r[SVR4_X86_GS] = rgs(); + r[SVR4_X86_FS] = tf->tf_fs; +#endif r[SVR4_X86_ES] = tf->tf_es; r[SVR4_X86_DS] = tf->tf_ds; r[SVR4_X86_EFL] = tf->tf_eflags; @@ -230,7 +235,12 @@ svr4_setcontext(p, uc) !USERMODE(r[SVR4_X86_CS], r[SVR4_X86_EFL])) return (EINVAL); +#if defined(__NetBSD__) /* %fs and %gs were restored by the trampoline. */ +#else + /* %gs was restored by the trampoline. */ + tf->tf_fs = r[SVR4_X86_FS]; +#endif tf->tf_es = r[SVR4_X86_ES]; tf->tf_ds = r[SVR4_X86_DS]; tf->tf_eflags = r[SVR4_X86_EFL]; @@ -449,6 +459,7 @@ svr4_sendsig(catcher, sig, mask, code) tf->tf_cs = _ucodesel; tf->tf_ds = _udatasel; tf->tf_es = _udatasel; + tf->tf_fs = _udatasel; tf->tf_ss = _udatasel; #endif } diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 8d9377e6b0fe..bf6ec7f4b4eb 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.112 1999/04/20 21:15:13 des Exp $ + * $Id: init_main.c,v 1.113 1999/04/24 18:50:48 dt Exp $ */ #include "opt_devfs.h" @@ -232,14 +232,12 @@ restart: break; case SI_TYPE_KTHREAD: -#if !defined(SMP) /* kernel thread*/ if (fork1(&proc0, RFMEM|RFFDG|RFPROC)) panic("fork kernel thread"); cpu_set_fork_handler(pfind(proc0.p_retval[0]), (*sipp)->func, (*sipp)->udata); break; -#endif case SI_TYPE_KPROCESS: if (fork1(&proc0, RFFDG|RFPROC)) @@ -360,7 +358,6 @@ proc0_init(dummy) * any possible traps/probes to simplify trap processing. */ p = &proc0; - curproc = p; /* XXX redundant*/ /* * Initialize process and pgrp structures. diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 0ffc9bb8bb6d..0e97656ce99f 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 - * $Id: kern_exit.c,v 1.77 1999/03/11 21:53:12 bde Exp $ + * $Id: kern_exit.c,v 1.78 1999/04/17 08:36:04 peter Exp $ */ #include "opt_compat.h" @@ -350,7 +350,7 @@ exit1(p, rv) * * Other substructures are freed from wait(). */ - curproc = NULL; + SET_CURPROC(NULL); if (--p->p_limit->p_refcnt == 0) { FREE(p->p_limit, M_SUBPROC); p->p_limit = NULL; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 801b90c03124..d3f40ea68514 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 - * $Id: kern_fork.c,v 1.58 1999/04/17 08:36:04 peter Exp $ + * $Id: kern_fork.c,v 1.59 1999/04/24 11:25:01 dt Exp $ */ #include "opt_ktrace.h" @@ -65,11 +65,7 @@ #include #include -#ifdef SMP -static int fast_vfork = 0; /* Doesn't work on SMP yet. */ -#else static int fast_vfork = 1; -#endif SYSCTL_INT(_kern, OID_AUTO, fast_vfork, CTLFLAG_RW, &fast_vfork, 0, ""); /* @@ -140,22 +136,6 @@ fork1(p1, flags) if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) return (EINVAL); -#ifdef SMP - /* - * FATAL now, we cannot have the same PTD on both cpus, the PTD - * needs to move out of PTmap and be per-process, even for shared - * page table processes. Unfortunately, this means either removing - * PTD[] as a fixed virtual address, or move it to the per-cpu map - * area for SMP mode. Both cases require seperate management of - * the per-process-even-if-PTmap-is-shared PTD. - */ - if (flags & RFMEM) { - printf("shared address space fork attempted: pid: %d\n", - p1->p_pid); - return (EOPNOTSUPP); - } -#endif - /* * Here we don't create a new process, but we divorce * certain parts of a process from itself. diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index b184a98b2f2e..ba60a8bb03cd 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_linker.c,v 1.29 1999/04/06 03:02:11 peter Exp $ + * $Id: kern_linker.c,v 1.30 1999/04/27 11:15:57 phk Exp $ */ #include "opt_ddb.h" @@ -151,14 +151,12 @@ linker_file_sysinit(linker_file_t lf) break; case SI_TYPE_KTHREAD: -#if !defined(SMP) /* kernel thread*/ if (fork1(&proc0, RFFDG|RFPROC|RFMEM)) panic("fork kernel thread"); cpu_set_fork_handler(pfind(proc0.p_retval[0]), (*sipp)->func, (*sipp)->udata); break; -#endif case SI_TYPE_KPROCESS: /* kernel thread*/ diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index eca2601a70b2..dcca437e8a10 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.96 1999/04/11 00:43:43 tegge Exp $ + * $Id: mp_machdep.c,v 1.97 1999/04/13 03:24:47 tegge Exp $ */ #include "opt_smp.h" @@ -297,28 +297,15 @@ int apic_id_to_logical[NAPICID]; /* Bitmap of all available CPUs */ u_int all_cpus; -/* AP uses this PTD during bootstrap. Do not staticize. */ -pd_entry_t *bootPTD; +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +int boot_cpuid; /* Hotwire a 0->4MB V==P mapping */ extern pt_entry_t *KPTphys; -/* Virtual address of per-cpu common_tss */ -extern struct i386tss common_tss; -#ifdef VM86 -extern struct segment_descriptor common_tssd; -extern u_int private_tss; /* flag indicating private tss */ -extern u_int my_tr; -#endif /* VM86 */ - -/* IdlePTD per cpu */ -pd_entry_t *IdlePTDS[NCPU]; - -/* "my" private page table page, for BSP init */ -extern pt_entry_t SMP_prvpt[]; - -/* Private page pointer to curcpu's PTD, used during BSP init */ -extern pd_entry_t *my_idlePTD; +/* SMP page table page */ +extern pt_entry_t *SMPpt; struct pcb stoppcbs[NCPU]; @@ -466,41 +453,42 @@ void init_secondary(void) { int gsel_tss; -#ifndef VM86 - u_int my_tr; -#endif + int x, myid = boot_cpuid; - r_gdt.rd_limit = sizeof(gdt[0]) * (NGDT + NCPU) - 1; - r_gdt.rd_base = (int) gdt; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].globaldata.gd_common_tss; + SMP_prvspace[myid].globaldata.gd_prvspace = &SMP_prvspace[myid]; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ + lidt(&r_idt); + lldt(_default_ldt); #ifdef USER_LDT currentldt = _default_ldt; #endif - my_tr = NGDT + cpuid; - gsel_tss = GSEL(my_tr, SEL_KPL); - gdt[my_tr].sd.sd_type = SDT_SYS386TSS; + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; common_tss.tss_esp0 = 0; /* not used until after switch */ common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); common_tss.tss_ioopt = (sizeof common_tss) << 16; #ifdef VM86 - common_tssd = gdt[my_tr].sd; - private_tss = 0; -#endif /* VM86 */ + common_tssd = gdt[myid * NGDT + GPROC0_SEL].sd; +#endif ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ - PTD[0] = 0; pmap_set_opt((unsigned *)PTD); -#if 0 - putmtrr(); - pmap_setvidram(); -#endif - invltlb(); } @@ -558,11 +546,6 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ -#if 0 - getmtrr(); - pmap_setvidram(); -#endif - POSTCODE(MP_ENABLE_POST); /* turn on 4MB of V == P addressing so we can get to MP table */ @@ -1770,14 +1753,11 @@ extern int wait_ap(unsigned int); static int start_all_aps(u_int boot_addr) { - int x, i; + int x, i, pg; u_char mpbiosreason; u_long mpbioswarmvec; - pd_entry_t *newptd; - pt_entry_t *newpt; struct globaldata *gd; char *stack; - pd_entry_t *myPTD; POSTCODE(START_ALL_APS_POST); @@ -1799,70 +1779,46 @@ start_all_aps(u_int boot_addr) /* record BSP in CPU map */ all_cpus = 1; + /* set up 0 -> 4MB P==V mapping for AP boot */ + *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); + invltlb(); + /* start each AP */ for (x = 1; x <= mp_naps; ++x) { /* This is a bit verbose, it will go away soon. */ - /* alloc new page table directory */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* Store the virtual PTD address for this CPU */ - IdlePTDS[x] = newptd; - - /* clone currently active one (ie: IdlePTD) */ - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - - /* set up 0 -> 4MB P==V mapping for AP boot */ - newptd[0] = (void *)(uintptr_t)(PG_V | PG_RW | - ((uintptr_t)(void *)KPTphys & PG_FRAME)); - - /* store PTD for this AP's boot sequence */ - myPTD = (pd_entry_t *)vtophys(newptd); - - /* alloc new page table page */ - newpt = (pt_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - /* set the new PTD's private page to point there */ - newptd[MPPTDI] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* install self referential entry */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); + /* first page of AP's private space */ + pg = x * i386_btop(sizeof(struct privatespace)); /* allocate a new private data page */ gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE); /* wire it into the private page table page */ - newpt[0] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); - - /* wire the ptp into itself for access */ - newpt[1] = (pt_entry_t)(PG_V | PG_RW | vtophys(newpt)); - - /* copy in the pointer to the local apic */ - newpt[2] = SMP_prvpt[2]; - - /* and the IO apic mapping[s] */ - for (i = 16; i < 32; i++) - newpt[i] = SMP_prvpt[i]; + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd)); /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - newpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[pg + 5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); - newpt[3 + UPAGES] = 0; /* *prv_CMAP1 */ - newpt[4 + UPAGES] = 0; /* *prv_CMAP2 */ - newpt[5 + UPAGES] = 0; /* *prv_CMAP3 */ - newpt[6 + UPAGES] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ + SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ + SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ + SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ /* prime data page for it to use */ - gd->cpuid = x; - gd->cpu_lockid = x << 24; - gd->my_idlePTD = myPTD; - gd->prv_CMAP1 = &newpt[3 + UPAGES]; - gd->prv_CMAP2 = &newpt[4 + UPAGES]; - gd->prv_CMAP3 = &newpt[5 + UPAGES]; - gd->prv_PMAP1 = &newpt[6 + UPAGES]; + gd->gd_cpuid = x; + gd->gd_cpu_lockid = x << 24; + gd->gd_prv_CMAP1 = &SMPpt[pg + 1]; + gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; + gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; + gd->gd_prv_PMAP1 = &SMPpt[pg + 4]; + gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; + gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; + gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; + gd->gd_prv_PADDR1 = (unsigned *)SMP_prvspace[x].PPAGE1; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -1872,7 +1828,9 @@ start_all_aps(u_int boot_addr) outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ #endif - bootPTD = myPTD; + bootSTK = &SMP_prvspace[x].idlestack[UPAGES*PAGE_SIZE]; + boot_cpuid = x; + /* attempt to start the Application Processor */ CHECK_INIT(99); /* setup checkpoints */ if (!start_ap(x, boot_addr)) { @@ -1910,27 +1868,16 @@ start_all_aps(u_int boot_addr) * because the BSP is cpu#0 and the page is initially zero, and also * because we can refer to variables by name on the BSP.. */ - newptd = (pd_entry_t *)(kmem_alloc(kernel_map, PAGE_SIZE)); - - bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ - IdlePTDS[0] = newptd; - - /* Point PTD[] to this page instead of IdlePTD's physical page */ - newptd[PTDPTDI] = (pd_entry_t)(PG_V | PG_RW | vtophys(newptd)); - - my_idlePTD = (pd_entry_t *)vtophys(newptd); /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMP_prvpt[i + 3] = (pt_entry_t)(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + SMPpt[5 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + *(int *)PTD = 0; pmap_set_opt_bsp(); - for (i = 0; i < mp_ncpus; i++) { - bcopy( (int *) PTD + KPTDI, (int *) IdlePTDS[i] + KPTDI, NKPDE * sizeof (int)); - } - /* number of APs actually started */ return mp_ncpus - 1; } @@ -2250,10 +2197,6 @@ ap_init() panic("cpuid mismatch! boom!!"); } -#if 0 - getmtrr(); -#endif - /* Init local apic for irq's */ apic_initialize(); @@ -2267,8 +2210,6 @@ ap_init() smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ smp_active = 1; /* historic */ } - - curproc = NULL; /* make sure */ } #ifdef BETTER_CLOCK diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index d08306e99ce8..c0807b0787a5 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.134 1999/03/09 20:20:09 phk Exp $ + * $Id: trap.c,v 1.135 1999/04/19 14:14:13 peter Exp $ */ /* @@ -101,8 +101,6 @@ #include "isa.h" #include "npx.h" -extern struct i386tss common_tss; - int (*pmath_emulate) __P((struct trapframe *)); extern void trap __P((struct trapframe frame)); @@ -480,11 +478,6 @@ kernel_trap: * (XXX) so that we can continue, and generate * a signal. */ - if (frame.tf_eip == (int)cpu_switch_load_fs) { - curpcb->pcb_fs = 0; - psignal(p, SIGBUS); - return; - } if (frame.tf_eip == (int)cpu_switch_load_gs) { curpcb->pcb_gs = 0; psignal(p, SIGBUS); @@ -496,6 +489,8 @@ kernel_trap: doreti_popl_ds_fault); MAYBE_DORETI_FAULT(doreti_popl_es, doreti_popl_es_fault); + MAYBE_DORETI_FAULT(doreti_popl_fs, + doreti_popl_fs_fault); if (curpcb && curpcb->pcb_onfault) { frame.tf_eip = (int)curpcb->pcb_onfault; return; diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 0c4f44884499..577c4996b5b6 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -13,7 +13,7 @@ * bad that happens because of using this software isn't the responsibility * of the author. This software is distributed AS-IS. * - * $Id: vfs_aio.c,v 1.44 1999/02/25 15:54:06 bde Exp $ + * $Id: vfs_aio.c,v 1.45 1999/04/04 21:41:16 dt Exp $ */ /* @@ -243,11 +243,6 @@ SYSINIT(aio, SI_SUB_VFS, SI_ORDER_ANY, aio_onceonly, NULL); static vm_zone_t kaio_zone=0, aiop_zone=0, aiocb_zone=0, aiol_zone=0, aiolio_zone=0; -/* - * Single AIOD vmspace shared amongst all of them - */ -struct vmspace *aiovmspace = NULL; - /* * Startup initialization */ @@ -607,7 +602,7 @@ aio_daemon(const void *uproc) { int s; struct aioproclist *aiop; - struct vmspace *myvm, *aiovm; + struct vmspace *myvm; struct proc *mycp; /* @@ -616,35 +611,6 @@ aio_daemon(const void *uproc) mycp = curproc; myvm = mycp->p_vmspace; - /* - * We manage to create only one VM space for all AIOD processes. - * The VM space for the first AIOD created becomes the shared VM - * space for all of them. We add an additional reference count, - * even for the first AIOD, so the address space does not go away, - * and we continue to use that original VM space even if the first - * AIOD exits. - */ - if ((aiovm = aiovmspace) == NULL) { - aiovmspace = myvm; - myvm->vm_refcnt++; - /* - * Remove userland cruft from address space. - */ - if (myvm->vm_shm) - shmexit(mycp); - pmap_remove_pages(vmspace_pmap(myvm), 0, USRSTACK); - vm_map_remove(&myvm->vm_map, 0, USRSTACK); - myvm->vm_tsize = 0; - myvm->vm_dsize = 0; - myvm->vm_ssize = 0; - } else { - aiovm->vm_refcnt++; - mycp->p_vmspace = aiovm; - pmap_activate(mycp); - vmspace_free(myvm); - myvm = aiovm; - } - if (mycp->p_textvp) { vrele(mycp->p_textvp); mycp->p_textvp = NULL; @@ -921,17 +887,13 @@ static int aio_newproc() { int error; - struct rfork_args rfa; struct proc *p, *np; - rfa.flags = RFPROC | RFCFDG; - - p = curproc; - if ((error = rfork(p, &rfa)) != 0) + p = &proc0; + if (error = fork1(p, RFPROC|RFMEM|RFNOWAIT)) return error; - np = pfind(p->p_retval[0]); - cpu_set_fork_handler(np, aio_daemon, p); + cpu_set_fork_handler(np, aio_daemon, curproc); /* * Wait until daemon is started, but continue on just in case (to diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 71271fbec7a8..12b809b7520f 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)proc.h 8.15 (Berkeley) 5/19/95 - * $Id: proc.h,v 1.78 1999/04/23 20:22:42 dt Exp $ + * $Id: proc.h,v 1.79 1999/04/27 11:18:32 phk Exp $ */ #ifndef _SYS_PROC_H_ @@ -325,14 +325,20 @@ extern u_long pidhash; extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl; extern u_long pgrphash; +#ifndef SET_CURPROC +#define SET_CURPROC(p) (curproc = (p)) +#endif + +#ifndef curproc extern struct proc *curproc; /* Current running proc. */ +extern int switchticks; /* `ticks' at last context switch. */ +extern struct timeval switchtime; /* Uptime at last context switch */ +#endif extern struct proc proc0; /* Process slot for swapper. */ extern int hogticks; /* Limit on kernel cpu hogs. */ extern int nprocs, maxproc; /* Current and max number of procs. */ extern int maxprocperuid; /* Max procs per uid. */ extern int sched_quantum; /* Scheduling quantum in ticks */ -extern int switchticks; /* `ticks' at last context switch. */ -extern struct timeval switchtime; /* Uptime at last context switch */ LIST_HEAD(proclist, proc); extern struct proclist allproc; /* List of all processes. */ diff --git a/sys/sys/smp.h b/sys/sys/smp.h index 0f4f915366b6..3750c72011eb 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ + * $Id: smp.h,v 1.44 1998/09/06 22:41:40 tegge Exp $ * */ @@ -112,7 +112,6 @@ struct apic_intmapinfo { }; extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; -extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; /* functions in mp_machdep.c */ @@ -175,12 +174,6 @@ extern int invltlb_ok; extern int smp_active; extern volatile int smp_idle_loops; -/* 'private' global data in locore.s */ -extern volatile u_int cpuid; -extern volatile u_int cpu_lockid; -extern int inside_intr; -extern volatile u_int other_cpus; - #endif /* !LOCORE */ #endif /* SMP || APIC_IO */ #endif /* KERNEL */