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	<alc@cs.rice.edu>
		John Dyson	<dyson@iquest.net>
		Julian Elischer	<julian@whistel.com>
		Bruce Evans	<bde@zeta.org.au>
		David Greenman	<dg@root.com>
This commit is contained in:
Luoqi Chen 1999-04-28 01:04:33 +00:00
parent a261bdc7a2
commit 5206bca10a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46129
92 changed files with 1849 additions and 2001 deletions

View File

@ -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 <sys/param.h>
@ -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));

View File

@ -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;

View File

@ -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<<id) */
btsl %eax, _checkstate_probed_cpus
popl %fs
popl %ds /* restore previous data segment */
popl %ebx
popl %eax
@ -644,6 +669,8 @@ _Xcpuast:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl _cpuid, %eax
lock /* checkstate_need_ast &= ~(1<<id) */
@ -654,7 +681,7 @@ _Xcpuast:
btsl %eax, _checkstate_pending_ast
jc 1f
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
/*
* Giant locks do not come cheap.
@ -709,10 +736,12 @@ _Xforward_irq:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl $0, lapic_eoi /* End Of Interrupt to APIC */
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
ISR_TRYLOCK
testl %eax,%eax /* Did we get the lock ? */
@ -812,10 +841,12 @@ _Xcpustop:
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
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 */
@ -850,7 +881,7 @@ _Xcpustop:
call %eax
2:
popl %es
popl %fs
popl %ds /* restore previous data segment */
popl %edx
popl %ecx

View File

@ -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

View File

@ -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);

View File

@ -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 <sys/param.h>
@ -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 },

View File

@ -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

View File

@ -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

View File

@ -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 <machine/apic.h>
#endif
#ifdef VM86
#include <machine/segments.h>
#endif
#include <machine/globaldata.h>
#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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
#ifdef SMP
#include <machine/smp.h>
#include <machine/globaldata.h>
#endif
#ifdef PERFMON
#include <machine/perfmon.h>
@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
@ -100,6 +102,9 @@
#if defined(SMP) || defined(APIC_IO)
#include <machine/smp.h>
#include <machine/apic.h>
#include <machine/segments.h>
#include <machine/tss.h>
#include <machine/globaldata.h>
#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;

View File

@ -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 <machine/asmacros.h>
@ -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

View File

@ -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 <machine/asmacros.h>
@ -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

View File

@ -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

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
@ -54,6 +55,7 @@
#include <machine/cpu.h>
#include <machine/pcb_ext.h> /* pcb.h included by sys/user.h */
#include <machine/sysarch.h>
#include <machine/smp.h>
#include <vm/vm_kern.h> /* 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);
}

View File

@ -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 @@ trap(frame)
* (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 @@ trap(frame)
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;

View File

@ -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__ */

View File

@ -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 <machine/globals.h>
/* 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));

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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 <machine/globals.h>
/* 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));

View File

@ -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 <machine/globals.h>
#include <machine/npx.h>
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

View File

@ -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

View File

@ -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/globals.h>
/*
* Machine-dependent part of the proc structure for i386.
*/

View File

@ -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;
};

View File

@ -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 <machine/globals.h>
/*
* 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[];

View File

@ -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 */

View File

@ -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 <machine/globals.h>
/*
* 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_ */

View File

@ -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 ; \

View File

@ -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 ; \

View File

@ -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 ; \

View File

@ -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 <sys/param.h>
@ -531,18 +531,18 @@ linux_newselect(struct proc *p, struct linux_newselect_args *args)
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);

View File

@ -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<<id) */
btsl %eax, _checkstate_probed_cpus
popl %fs
popl %ds /* restore previous data segment */
popl %ebx
popl %eax
@ -644,6 +669,8 @@ _Xcpuast:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl _cpuid, %eax
lock /* checkstate_need_ast &= ~(1<<id) */
@ -654,7 +681,7 @@ _Xcpuast:
btsl %eax, _checkstate_pending_ast
jc 1f
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
/*
* Giant locks do not come cheap.
@ -709,10 +736,12 @@ _Xforward_irq:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl $0, lapic_eoi /* End Of Interrupt to APIC */
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
ISR_TRYLOCK
testl %eax,%eax /* Did we get the lock ? */
@ -812,10 +841,12 @@ _Xcpustop:
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
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 */
@ -850,7 +881,7 @@ _Xcpustop:
call %eax
2:
popl %es
popl %fs
popl %ds /* restore previous data segment */
popl %edx
popl %ecx

View File

@ -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);

View File

@ -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 <sys/param.h>
@ -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 },

View File

@ -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

View File

@ -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 <machine/apic.h>
#endif
#ifdef VM86
#include <machine/segments.h>
#endif
#include <machine/globaldata.h>
#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);
}

View File

@ -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)

View File

@ -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 */

View File

@ -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 <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
#ifdef SMP
#include <machine/smp.h>
#include <machine/globaldata.h>
#endif
#ifdef PERFMON
#include <machine/perfmon.h>
@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
@ -100,6 +102,9 @@
#if defined(SMP) || defined(APIC_IO)
#include <machine/smp.h>
#include <machine/apic.h>
#include <machine/segments.h>
#include <machine/tss.h>
#include <machine/globaldata.h>
#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;

View File

@ -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 <machine/asmacros.h>
@ -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

View File

@ -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

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
@ -54,6 +55,7 @@
#include <machine/cpu.h>
#include <machine/pcb_ext.h> /* pcb.h included by sys/user.h */
#include <machine/sysarch.h>
#include <machine/smp.h>
#include <vm/vm_kern.h> /* 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);
}

View File

@ -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 @@ trap(frame)
* (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 @@ trap(frame)
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;

View File

@ -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 <machine/specialreg.h>
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);

View File

@ -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

View File

@ -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_ */

View File

@ -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__ */

View File

@ -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;

View File

@ -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

147
sys/i386/include/globals.h Normal file
View File

@ -0,0 +1,147 @@
/*-
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
* 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_ */

View File

@ -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));

View File

@ -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

View File

@ -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 <machine/globals.h>
/* 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));

View File

@ -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 <machine/globals.h>
#include <machine/npx.h>
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

View File

@ -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

View File

@ -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/globals.h>
/*
* Machine-dependent part of the proc structure for i386.
*/

View File

@ -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;
};

View File

@ -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 <machine/globals.h>
/*
* 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[];

View File

@ -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 */

View File

@ -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 <machine/globals.h>
/*
* 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_ */

View File

@ -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 <machine/frame.h> */
struct vm86frame {
int kernel_fs;
int kernel_es;
int kernel_ds;
reg86_t edi;

View File

@ -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<<id) */
btsl %eax, _checkstate_probed_cpus
popl %fs
popl %ds /* restore previous data segment */
popl %ebx
popl %eax
@ -644,6 +669,8 @@ _Xcpuast:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl _cpuid, %eax
lock /* checkstate_need_ast &= ~(1<<id) */
@ -654,7 +681,7 @@ _Xcpuast:
btsl %eax, _checkstate_pending_ast
jc 1f
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
/*
* Giant locks do not come cheap.
@ -709,10 +736,12 @@ _Xforward_irq:
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl %ax, %es
movl $KPSEL, %eax
movl %ax, %fs
movl $0, lapic_eoi /* End Of Interrupt to APIC */
FAKE_MCOUNT(12*4(%esp))
FAKE_MCOUNT(13*4(%esp))
ISR_TRYLOCK
testl %eax,%eax /* Did we get the lock ? */
@ -812,10 +841,12 @@ _Xcpustop:
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
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 */
@ -850,7 +881,7 @@ _Xcpustop:
call %eax
2:
popl %es
popl %fs
popl %ds /* restore previous data segment */
popl %edx
popl %ecx

View File

@ -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 ; \

View File

@ -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 ; \

View File

@ -36,7 +36,7 @@
*
* @(#)ipl.s
*
* $Id: ipl.s,v 1.24 1998/08/11 17:01:32 bde Exp $
* $Id: ipl.s,v 1.25 1999/04/11 15:51:15 peter Exp $
*/
@ -173,7 +173,7 @@ doreti_exit:
je 1f
testl $PSL_VM,TF_EFLAGS(%esp) /* going to VM86 mode? */
jne doreti_stop
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp) /* to user mode? */
testb $SEL_RPL_MASK,TF_CS(%esp) /* to user mode? */
je 1f
doreti_stop:
movl $0,_cpl
@ -192,6 +192,9 @@ doreti_stop:
add $4, %esp
#endif /* SMP */
.globl doreti_popl_fs
doreti_popl_fs:
popl %fs
.globl doreti_popl_es
doreti_popl_es:
popl %es
@ -215,8 +218,11 @@ doreti_popl_ds_fault:
pushl %es
.globl doreti_popl_es_fault
doreti_popl_es_fault:
movl $0,4+4+32+4(%esp) /* XXX should be the error code */
movl $T_PROTFLT,4+4+32+0(%esp)
pushl %fs
.globl doreti_popl_fs_fault
doreti_popl_fs_fault:
movl $0,TF_ERR(%esp) /* XXX should be the error code */
movl $T_PROTFLT,TF_TRAPNO(%esp)
jmp alltraps_with_regs_pushed
ALIGN_TEXT
@ -343,10 +349,10 @@ swi_ast:
cmpl $1,_in_vm86call
je 1f /* stay in kernel mode */
#endif
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
testb $SEL_RPL_MASK,TF_CS(%esp)
je swi_ast_phantom
swi_ast_user:
movl $T_ASTFLT,(2+8+0)*4(%esp)
movl $T_ASTFLT,TF_TRAPNO(%esp)
movb $0,_intr_nesting_level /* finish becoming a trap handler */
call _trap
subl %eax,%eax /* recover cpl|cml */

View File

@ -23,12 +23,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ipl_funcs.c,v 1.15 1999/03/05 23:39:02 gibbs Exp $
* $Id: ipl_funcs.c,v 1.16 1999/04/21 07:26:27 peter Exp $
*/
#include <sys/types.h>
#include <sys/systm.h>
#include <machine/ipl.h>
#include <machine/globals.h>
#ifndef SMP
/*

View File

@ -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 <sys/param.h>
@ -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));

View File

@ -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() */

View File

@ -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 <sys/param.h>
@ -531,18 +531,18 @@ linux_newselect(struct proc *p, struct linux_newselect_args *args)
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);

View File

@ -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;

View File

@ -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

View File

@ -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
}

View File

@ -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 @@ main(framep)
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.

View File

@ -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;

View File

@ -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 <machine/frame.h>
#include <sys/user.h>
#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.

View File

@ -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*/

View File

@ -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

View File

@ -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 @@ trap(frame)
* (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 @@ trap(frame)
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;

View File

@ -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

View File

@ -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. */

View File

@ -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 */