* Applied fixes from Bruce Evans to fix COW bugs, >1MB kernel loading,
profiling, and various protection checks that cause security holes and system crashes. * Changed min/max/bcmp/ffs/strlen to be static inline functions - included from cpufunc.h in via systm.h. This change improves performance in many parts of the kernel - up to 5% in the networking layer alone. Note that this requires systm.h to be included in any file that uses these functions otherwise it won't be able to find them during the load. * Fixed incorrect call to splx() in if_is.c * Fixed bogus variable assignment to splx() in if_ed.c
This commit is contained in:
parent
af7f5fbec0
commit
269312019a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200
@ -89,9 +89,35 @@
|
|||||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
||||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
||||||
|
|
||||||
#define LENTRY(name) ALIGN_TEXT; .globl name; name:
|
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
|
||||||
#define ENTRY(name) ALIGN_TEXT; .globl _/**/name; _/**/name:
|
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
#define ALTENTRY(name) .globl _/**/name; _/**/name:
|
|
||||||
|
#ifdef GPROF
|
||||||
|
/*
|
||||||
|
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
|
||||||
|
* over the mcounting.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; jmp 2f
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; 2:
|
||||||
|
/*
|
||||||
|
* The call to mcount supports the usual (bad) conventions. We allocate
|
||||||
|
* some data and pass a pointer to it although the 386BSD doesn't use
|
||||||
|
* the data. We set up a frame before calling mcount because that is
|
||||||
|
* the standard convention although it makes work for both mcount and
|
||||||
|
* callers.
|
||||||
|
*/
|
||||||
|
#define MCOUNT .data; ALIGN_DATA; 1:; .long 0; .text; \
|
||||||
|
pushl %ebp; movl %esp, %ebp; \
|
||||||
|
movl $1b,%eax; call mcount; popl %ebp
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* ALTENTRY() has to align because it is before a corresponding ENTRY().
|
||||||
|
* ENTRY() has to align to because there may be no ALTENTRY() before it.
|
||||||
|
* If there is a previous ALTENTRY() then the alignment code is empty.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
||||||
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
||||||
@ -143,10 +169,11 @@
|
|||||||
.globl _boothowto, _bootdev, _curpcb
|
.globl _boothowto, _bootdev, _curpcb
|
||||||
.globl __ucodesel,__udatasel
|
.globl __ucodesel,__udatasel
|
||||||
|
|
||||||
.globl _cpu, _cold, _atdevbase, _atdevphys
|
.globl _cpu, _cold, _atdevbase
|
||||||
_cpu: .long 0 # are we 386, 386sx, or 486
|
_cpu: .long 0 # are we 386, 386sx, or 486
|
||||||
_cold: .long 1 # cold till we are not
|
_cold: .long 1 # cold till we are not
|
||||||
_atdevbase: .long 0 # location of start of iomem in virtual
|
_atdevbase: .long 0 # location of start of iomem in virtual
|
||||||
|
# .nonglobl _atdevphys (should be register or something)
|
||||||
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
||||||
|
|
||||||
.globl _IdlePTD, _KPTphys
|
.globl _IdlePTD, _KPTphys
|
||||||
@ -158,7 +185,8 @@ _cyloffset: .long 0
|
|||||||
_proc0paddr: .long 0
|
_proc0paddr: .long 0
|
||||||
|
|
||||||
#ifdef SHOW_A_LOT
|
#ifdef SHOW_A_LOT
|
||||||
bit_colors: .byte GREEN,RED,0,0
|
bit_colors:
|
||||||
|
.byte GREEN,RED,0,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.space 512
|
.space 512
|
||||||
@ -171,11 +199,11 @@ tmpstk:
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* start: jumped to directly from the boot blocks
|
* btext: beginning of text section.
|
||||||
|
* Also the entry point (jumped to directly from the boot blocks).
|
||||||
*/
|
*/
|
||||||
LENTRY(start)
|
ENTRY(btext)
|
||||||
movw $0x1234,%ax
|
movw $0x1234, 0x472 # warm boot
|
||||||
movw %ax,0x472 # warm boot
|
|
||||||
jmp 1f
|
jmp 1f
|
||||||
.space 0x500 # skip over warm boot shit
|
.space 0x500 # skip over warm boot shit
|
||||||
|
|
||||||
@ -278,7 +306,10 @@ LENTRY(start)
|
|||||||
movl %esi,%ecx # this much memory,
|
movl %esi,%ecx # this much memory,
|
||||||
shrl $ PGSHIFT,%ecx # for this many pte s
|
shrl $ PGSHIFT,%ecx # for this many pte s
|
||||||
addl $ UPAGES+4,%ecx # including our early context
|
addl $ UPAGES+4,%ecx # including our early context
|
||||||
movl $0xa0,%ecx # XXX - cover debugger pages
|
cmpl $0xa0,%ecx # XXX - cover debugger pages
|
||||||
|
jae 1f
|
||||||
|
movl $0xa0,%ecx
|
||||||
|
1:
|
||||||
movl $PG_V|PG_KW,%eax # having these bits set,
|
movl $PG_V|PG_KW,%eax # having these bits set,
|
||||||
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
||||||
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
||||||
@ -372,9 +403,15 @@ LENTRY(start)
|
|||||||
|
|
||||||
/* load base of page directory, and enable mapping */
|
/* load base of page directory, and enable mapping */
|
||||||
movl %esi,%eax # phys address of ptd in proc 0
|
movl %esi,%eax # phys address of ptd in proc 0
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3 # load ptd addr into mmu
|
movl %eax,%cr3 # load ptd addr into mmu
|
||||||
movl %cr0,%eax # get control word
|
movl %cr0,%eax # get control word
|
||||||
|
/*
|
||||||
|
* XXX it is now safe to always (attempt to) set CR0_WP and to set up
|
||||||
|
* the page tables assuming it works, so USE_486_WRITE_PROTECT will go
|
||||||
|
* away. The special 386 PTE checking needs to be conditional on
|
||||||
|
* whatever distingiushes 486-only kernels from 386-486 kernels.
|
||||||
|
*/
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
#ifdef USE_486_WRITE_PROTECT
|
||||||
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
||||||
#else
|
#else
|
||||||
@ -407,7 +444,7 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
|
|||||||
|
|
||||||
lea 7*NBPG(%esi),%esi # skip past stack.
|
lea 7*NBPG(%esi),%esi # skip past stack.
|
||||||
pushl %esi
|
pushl %esi
|
||||||
|
|
||||||
/* relocate debugger gdt entries */
|
/* relocate debugger gdt entries */
|
||||||
|
|
||||||
movl $_gdt+8*9,%eax # adjust slots 9-17
|
movl $_gdt+8*9,%eax # adjust slots 9-17
|
||||||
@ -423,9 +460,9 @@ reloc_gdt:
|
|||||||
1:
|
1:
|
||||||
|
|
||||||
call _init386 # wire 386 chip for unix operation
|
call _init386 # wire 386 chip for unix operation
|
||||||
|
|
||||||
movl $0,_PTD
|
movl $0,_PTD
|
||||||
call _main # autoconfiguration, mountroot etc
|
call _main # autoconfiguration, mountroot etc
|
||||||
popl %esi
|
popl %esi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -459,9 +496,11 @@ lretmsg1:
|
|||||||
/*
|
/*
|
||||||
* Icode is copied out to process 1 and executed in user mode:
|
* Icode is copied out to process 1 and executed in user mode:
|
||||||
* execve("/sbin/init", argv, envp); exit(0);
|
* execve("/sbin/init", argv, envp); exit(0);
|
||||||
* If the exec fails, process 1 exits and the system panics.
|
* If the execve fails, process 1 exits and the system panics.
|
||||||
*/
|
*/
|
||||||
ENTRY(icode)
|
NON_GPROF_ENTRY(icode)
|
||||||
|
pushl $0 # envp
|
||||||
|
|
||||||
# pushl $argv-_icode # gas fucks up again
|
# pushl $argv-_icode # gas fucks up again
|
||||||
movl $argv,%eax
|
movl $argv,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
@ -471,14 +510,17 @@ ENTRY(icode)
|
|||||||
movl $init,%eax
|
movl $init,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
pushl %eax
|
pushl %eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
|
|
||||||
movl %esp,%ebp
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exec,%eax
|
movl $exec,%eax
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
pushl %eax
|
|
||||||
|
pushl %eax # execve failed, the errno will do for an
|
||||||
|
# exit code because errnos are < 128
|
||||||
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exit,%eax
|
movl $exit,%eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@ -494,7 +536,7 @@ eicode:
|
|||||||
_szicode:
|
_szicode:
|
||||||
.long _szicode-_icode
|
.long _szicode-_icode
|
||||||
|
|
||||||
ENTRY(sigcode)
|
NON_GPROF_ENTRY(sigcode)
|
||||||
call 12(%esp)
|
call 12(%esp)
|
||||||
lea 28(%esp),%eax # scp (the call may have clobbered the
|
lea 28(%esp),%eax # scp (the call may have clobbered the
|
||||||
# copy at 8(%esp))
|
# copy at 8(%esp))
|
||||||
@ -640,7 +682,7 @@ ENTRY(bzero) # void bzero(void *base, u_int cnt)
|
|||||||
movl 8(%esp),%edi
|
movl 8(%esp),%edi
|
||||||
movl 12(%esp),%ecx
|
movl 12(%esp),%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
shrl $2,%ecx
|
shrl $2,%ecx
|
||||||
cld
|
cld
|
||||||
rep
|
rep
|
||||||
stosl
|
stosl
|
||||||
@ -664,6 +706,7 @@ ENTRY(fillw) # fillw (pat,base,cnt)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyb)
|
ENTRY(bcopyb)
|
||||||
|
bcopyb:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -672,7 +715,7 @@ ENTRY(bcopyb)
|
|||||||
cmpl %esi,%edi /* potentially overlapping? */
|
cmpl %esi,%edi /* potentially overlapping? */
|
||||||
jnb 1f
|
jnb 1f
|
||||||
cld /* nope, copy forwards */
|
cld /* nope, copy forwards */
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -693,6 +736,7 @@ ENTRY(bcopyb)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyw)
|
ENTRY(bcopyw)
|
||||||
|
bcopyw:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -735,20 +779,18 @@ ENTRY(bcopyw)
|
|||||||
ENTRY(bcopyx)
|
ENTRY(bcopyx)
|
||||||
movl 16(%esp),%eax
|
movl 16(%esp),%eax
|
||||||
cmpl $2,%eax
|
cmpl $2,%eax
|
||||||
je _bcopyw
|
je bcopyw /* not _bcopyw, to avoid multiple mcounts */
|
||||||
cmpl $4,%eax
|
cmpl $4,%eax
|
||||||
jne _bcopyb
|
je bcopy
|
||||||
/*
|
jmp bcopyb
|
||||||
* Fall through to bcopy. ENTRY() provides harmless fill bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (ov)bcopy (src,dst,cnt)
|
* (ov)bcopy (src,dst,cnt)
|
||||||
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
||||||
*/
|
*/
|
||||||
ENTRY(bcopy)
|
|
||||||
ALTENTRY(ovbcopy)
|
ALTENTRY(ovbcopy)
|
||||||
|
ENTRY(bcopy)
|
||||||
|
bcopy:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -789,8 +831,8 @@ ALTENTRY(ovbcopy)
|
|||||||
cld
|
cld
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohl)
|
ALTENTRY(ntohl)
|
||||||
ALTENTRY(htonl)
|
ENTRY(htonl)
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
#ifdef i486
|
#ifdef i486
|
||||||
/* XXX */
|
/* XXX */
|
||||||
@ -798,7 +840,7 @@ ALTENTRY(htonl)
|
|||||||
* equivalent bytes. This can be changed back to bswap when we
|
* equivalent bytes. This can be changed back to bswap when we
|
||||||
* upgrade to a newer version of Gas */
|
* upgrade to a newer version of Gas */
|
||||||
/* bswap %eax */
|
/* bswap %eax */
|
||||||
.byte 0x0f
|
.byte 0x0f
|
||||||
.byte 0xc8
|
.byte 0xc8
|
||||||
#else
|
#else
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
@ -807,8 +849,8 @@ ALTENTRY(htonl)
|
|||||||
#endif
|
#endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohs)
|
ALTENTRY(ntohs)
|
||||||
ALTENTRY(htons)
|
ENTRY(htons)
|
||||||
movzwl 4(%esp),%eax
|
movzwl 4(%esp),%eax
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
ret
|
ret
|
||||||
@ -861,10 +903,6 @@ show_bits:
|
|||||||
* protection violation occurs inside the functions, the trap handler
|
* protection violation occurs inside the functions, the trap handler
|
||||||
* returns to *curpcb->onfault instead of the function.
|
* returns to *curpcb->onfault instead of the function.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* XXX These routines load a segment register every time they execute.
|
|
||||||
* it would be nicer (faster) if they could depend on %gs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
||||||
@ -879,15 +917,36 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
orl %ebx, %ebx # nothing to do?
|
orl %ebx, %ebx # nothing to do?
|
||||||
jz done_copyout
|
jz done_copyout
|
||||||
|
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
/*
|
||||||
/* if WP bit in CR0 is set (n/a on 386), the hardware does the */
|
* Check explicitly for non-user addresses. If 486 write protection
|
||||||
/* write check. We just have to load the right segment selector */
|
* is being used, this check is essential because we are in kernel
|
||||||
pushl %es
|
* mode so the h/w does not provide any protection against writing
|
||||||
movl __udatasel, %eax
|
* kernel addresses.
|
||||||
movl %ax, %es
|
*
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
* Otherwise, it saves having to load and restore %es to get the
|
||||||
/* we have to check each PTE for (write) permission */
|
* usual segment-based protection (the destination segment for movs
|
||||||
|
* is always %es). The other explicit checks for user-writablility
|
||||||
|
* are not quite sufficient. They fail for the user area because
|
||||||
|
* we mapped the user area read/write to avoid having an #ifdef in
|
||||||
|
* vm_machdep.c. They fail for user PTEs and/or PTDs! (107
|
||||||
|
* addresses including 0xff800000 and 0xfc000000). I'm not sure if
|
||||||
|
* this can be fixed. Marking the PTEs supervisor mode and the
|
||||||
|
* PDE's user mode would almost work, but there may be a problem
|
||||||
|
* with the self-referential PDE.
|
||||||
|
*/
|
||||||
|
movl %edi, %eax
|
||||||
|
addl %ebx, %eax
|
||||||
|
jc copyout_fault
|
||||||
|
#define VM_END_USER_ADDRESS 0xFDBFE000 /* XXX */
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %eax
|
||||||
|
ja copyout_fault
|
||||||
|
|
||||||
|
#ifndef USE_486_WRITE_PROTECT
|
||||||
|
/*
|
||||||
|
* We have to check each PTE for user write permission.
|
||||||
|
* The checking may cause a page fault, so it is important to set
|
||||||
|
* up everything for return via copyout_fault before here.
|
||||||
|
*/
|
||||||
/* compute number of pages */
|
/* compute number of pages */
|
||||||
movl %edi, %ecx
|
movl %edi, %ecx
|
||||||
andl $0x0fff, %ecx
|
andl $0x0fff, %ecx
|
||||||
@ -906,7 +965,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
||||||
cmpb $0x07, %al
|
cmpb $0x07, %al
|
||||||
je 2f
|
je 2f
|
||||||
|
|
||||||
/* simulate a trap */
|
/* simulate a trap */
|
||||||
pushl %edx
|
pushl %edx
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
@ -924,8 +983,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
addl $4, %edx
|
addl $4, %edx
|
||||||
decl %ecx
|
decl %ecx
|
||||||
jnz 1b /* check next page */
|
jnz 1b /* check next page */
|
||||||
|
#endif /* ndef USE_486_WRITE_PROTECT */
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
|
||||||
|
|
||||||
/* now copy it over */
|
/* now copy it over */
|
||||||
/* bcopy (%esi, %edi, %ebx) */
|
/* bcopy (%esi, %edi, %ebx) */
|
||||||
@ -938,9 +996,6 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $3, %cl
|
andb $3, %cl
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
|
|
||||||
done_copyout:
|
done_copyout:
|
||||||
popl %ebx
|
popl %ebx
|
||||||
@ -951,10 +1006,8 @@ done_copyout:
|
|||||||
movl %eax,PCB_ONFAULT(%edx)
|
movl %eax,PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyout_fault:
|
copyout_fault:
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
popl %ebx
|
popl %ebx
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -972,22 +1025,19 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl 12(%esp),%esi # caddr_t from
|
movl 12(%esp),%esi # caddr_t from
|
||||||
movl 16(%esp),%edi # caddr_t to
|
movl 16(%esp),%edi # caddr_t to
|
||||||
movl 20(%esp),%ecx # size_t len
|
movl 20(%esp),%ecx # size_t len
|
||||||
movl %ecx,%edx
|
|
||||||
pushl %ds
|
|
||||||
movl __udatasel,%ax # access 'from' via user data segment
|
|
||||||
movl %ax,%ds
|
|
||||||
|
|
||||||
movb %cl,%al
|
movb %cl,%al
|
||||||
shrl $2,%ecx # copy longword-wise
|
shrl $2,%ecx # copy longword-wise
|
||||||
cld
|
cld
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsl
|
movsl
|
||||||
movb %al,%cl
|
movb %al,%cl
|
||||||
andb $3,%cl # copy remaining bytes
|
andb $3,%cl # copy remaining bytes
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
|
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
@ -995,8 +1045,8 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl %eax, PCB_ONFAULT(%edx)
|
movl %eax, PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyin_fault:
|
copyin_fault:
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
movl _curpcb, %edx
|
movl _curpcb, %edx
|
||||||
@ -1007,10 +1057,8 @@ copyin_fault:
|
|||||||
/*
|
/*
|
||||||
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
||||||
*/
|
*/
|
||||||
ENTRY(fuword)
|
|
||||||
ALTENTRY(fuiword)
|
ALTENTRY(fuiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(fuword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1018,10 +1066,8 @@ ALTENTRY(fuiword)
|
|||||||
movl (%edx),%eax
|
movl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fusword)
|
ENTRY(fusword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1029,11 +1075,9 @@ ENTRY(fusword)
|
|||||||
movzwl (%edx),%eax
|
movzwl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fubyte)
|
|
||||||
ALTENTRY(fuibyte)
|
ALTENTRY(fuibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(fubyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1041,7 +1085,8 @@ ALTENTRY(fuibyte)
|
|||||||
movzbl (%edx),%eax
|
movzbl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
fusufault:
|
fusufault:
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
@ -1056,42 +1101,39 @@ fusufault:
|
|||||||
/*
|
/*
|
||||||
* we only have to set the right segment selector.
|
* we only have to set the right segment selector.
|
||||||
*/
|
*/
|
||||||
ENTRY(suword)
|
|
||||||
ALTENTRY(suiword)
|
ALTENTRY(suiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(suword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movl 8(%esp),%eax
|
movl 8(%esp),%eax
|
||||||
gs
|
gs
|
||||||
movl %eax,(%edx)
|
movl %eax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(susword)
|
ENTRY(susword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movw 8(%esp),%ax
|
movw 8(%esp),%ax
|
||||||
gs
|
gs
|
||||||
movw %ax,(%edx)
|
movw %ax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(subyte)
|
|
||||||
ALTENTRY(suibyte)
|
ALTENTRY(suibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(subyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movb 8(%esp),%al
|
movb 8(%esp),%al
|
||||||
gs
|
gs
|
||||||
movb %al,(%edx)
|
movb %al,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -1102,8 +1144,8 @@ ALTENTRY(suibyte)
|
|||||||
*/
|
*/
|
||||||
# XXX - page boundary crossing is not handled yet
|
# XXX - page boundary crossing is not handled yet
|
||||||
|
|
||||||
|
ALTENTRY(suibyte)
|
||||||
ENTRY(subyte)
|
ENTRY(subyte)
|
||||||
ENTRY(suibyte)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1123,6 +1165,7 @@ ENTRY(suibyte)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movb %al, (%edx)
|
movb %al, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1149,14 +1192,15 @@ ENTRY(susword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movw %ax, (%edx)
|
movw %ax, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl %eax, PCB_ONFAULT(%ecx)
|
movl %eax, PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALTENTRY(suiword)
|
||||||
ENTRY(suword)
|
ENTRY(suword)
|
||||||
ENTRY(suiword)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1176,6 +1220,7 @@ ENTRY(suiword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movl %eax, 0(%edx)
|
movl %eax, 0(%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1183,6 +1228,7 @@ ENTRY(suiword)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* copyoutstr(from, to, maxlen, int *lencopied)
|
* copyoutstr(from, to, maxlen, int *lencopied)
|
||||||
* copy a string from from to to, stop when a 0 character is reached.
|
* copy a string from from to to, stop when a 0 character is reached.
|
||||||
@ -1201,13 +1247,19 @@ ENTRY(copyoutstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
decl %edx
|
decl %edx
|
||||||
jz 4f
|
jz 4f
|
||||||
|
/*
|
||||||
|
* gs override doesn't work for stosb. Use the same explicit check
|
||||||
|
* as in copyout(). It's much slower now because it is per-char.
|
||||||
|
* XXX - however, it would be faster to rewrite this function to use
|
||||||
|
* strlen() and copyout().
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
lodsb
|
lodsb
|
||||||
gs
|
gs
|
||||||
stosb
|
stosb
|
||||||
@ -1222,7 +1274,7 @@ ENTRY(copyoutstr)
|
|||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
#else /* ndef USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
ENTRY(copyoutstr)
|
ENTRY(copyoutstr)
|
||||||
pushl %esi
|
pushl %esi
|
||||||
@ -1234,6 +1286,13 @@ ENTRY(copyoutstr)
|
|||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
1:
|
1:
|
||||||
|
/*
|
||||||
|
* It suffices to check that the first byte is in user space, because
|
||||||
|
* we look at a page at a time and the end address is on a page
|
||||||
|
* boundary.
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
movl %edi, %eax
|
movl %edi, %eax
|
||||||
shrl $IDXSHIFT, %eax
|
shrl $IDXSHIFT, %eax
|
||||||
andb $0xfc, %al
|
andb $0xfc, %al
|
||||||
@ -1280,6 +1339,7 @@ ENTRY(copyoutstr)
|
|||||||
/* edx is zero -- return ENAMETOOLONG */
|
/* edx is zero -- return ENAMETOOLONG */
|
||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1298,8 +1358,6 @@ ENTRY(copyinstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
@ -1447,13 +1505,12 @@ ENTRY(ssdtosd) # ssdtosd(*ssdp,*sdp)
|
|||||||
|
|
||||||
ENTRY(tlbflush) # tlbflush()
|
ENTRY(tlbflush) # tlbflush()
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
ENTRY(lcr0) # lcr0(cr0)
|
ENTRY(load_cr0) # load_cr0(cr0)
|
||||||
ALTENTRY(load_cr0)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
movl %eax,%cr0
|
movl %eax,%cr0
|
||||||
ret
|
ret
|
||||||
@ -1470,18 +1527,13 @@ ENTRY(rcr2) # rcr2()
|
|||||||
|
|
||||||
|
|
||||||
ENTRY(rcr3) # rcr3()
|
ENTRY(rcr3) # rcr3()
|
||||||
ALTENTRY(_cr3)
|
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
/*
|
ENTRY(load_cr3) # void load_cr3(caddr_t cr3)
|
||||||
* void lcr3(caddr_t cr3)
|
|
||||||
*/
|
|
||||||
ENTRY(lcr3)
|
|
||||||
ALTENTRY(load_cr3)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1600,17 +1652,19 @@ sw0: .asciz "swtch"
|
|||||||
* When no processes are on the runq, Swtch branches to idle
|
* When no processes are on the runq, Swtch branches to idle
|
||||||
* to wait for something to come ready.
|
* to wait for something to come ready.
|
||||||
*/
|
*/
|
||||||
LENTRY(Idle)
|
ALIGN_TEXT
|
||||||
|
Idle:
|
||||||
sti
|
sti
|
||||||
SHOW_STI
|
SHOW_STI
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
idle_loop:
|
idle_loop:
|
||||||
call _spl0
|
call _spl0
|
||||||
cmpl $0,_whichqs
|
cmpl $0,_whichqs
|
||||||
jne sw1
|
jne sw1
|
||||||
hlt # wait for interrupt
|
hlt # wait for interrupt
|
||||||
jmp idle_loop
|
jmp idle_loop
|
||||||
|
|
||||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
|
||||||
badsw:
|
badsw:
|
||||||
pushl $sw0
|
pushl $sw0
|
||||||
call _panic
|
call _panic
|
||||||
@ -1619,6 +1673,7 @@ badsw:
|
|||||||
/*
|
/*
|
||||||
* Swtch()
|
* Swtch()
|
||||||
*/
|
*/
|
||||||
|
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||||
ENTRY(swtch)
|
ENTRY(swtch)
|
||||||
|
|
||||||
incl _cnt+V_SWTCH
|
incl _cnt+V_SWTCH
|
||||||
@ -1780,7 +1835,7 @@ ENTRY(savectx)
|
|||||||
movl 4(%esp), %ecx
|
movl 4(%esp), %ecx
|
||||||
movw _cpl, %ax
|
movw _cpl, %ax
|
||||||
movw %ax, PCB_IML(%ecx)
|
movw %ax, PCB_IML(%ecx)
|
||||||
movl (%esp), %eax
|
movl (%esp), %eax
|
||||||
movl %eax, PCB_EIP(%ecx)
|
movl %eax, PCB_EIP(%ecx)
|
||||||
movl %ebx, PCB_EBX(%ecx)
|
movl %ebx, PCB_EBX(%ecx)
|
||||||
movl %esp, PCB_ESP(%ecx)
|
movl %esp, PCB_ESP(%ecx)
|
||||||
@ -1885,7 +1940,7 @@ L1:
|
|||||||
proffault:
|
proffault:
|
||||||
/* if we get a fault, then kill profiling all together */
|
/* if we get a fault, then kill profiling all together */
|
||||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||||
movl 12(%ebp),%ecx
|
movl 12(%ebp),%ecx
|
||||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
@ -1903,7 +1958,7 @@ ENTRY(astoff)
|
|||||||
*
|
*
|
||||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||||
*/
|
*/
|
||||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||||
#ifdef KGDB
|
#ifdef KGDB
|
||||||
@ -2048,14 +2103,14 @@ bpttraps:
|
|||||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
||||||
# non-kernel mode?
|
# non-kernel mode?
|
||||||
jne calltrap # yes
|
jne calltrap # yes
|
||||||
call _kgdb_trap_glue
|
call _kgdb_trap_glue
|
||||||
jmp calltrap
|
jmp calltrap
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call gate entry for syscall
|
* Call gate entry for syscall
|
||||||
*/
|
*/
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
IDTVEC(syscall)
|
IDTVEC(syscall)
|
||||||
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
||||||
# XXX - also for direction flag (bzero, etc. clear it)
|
# XXX - also for direction flag (bzero, etc. clear it)
|
||||||
|
@ -89,9 +89,35 @@
|
|||||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
||||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
||||||
|
|
||||||
#define LENTRY(name) ALIGN_TEXT; .globl name; name:
|
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
|
||||||
#define ENTRY(name) ALIGN_TEXT; .globl _/**/name; _/**/name:
|
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
#define ALTENTRY(name) .globl _/**/name; _/**/name:
|
|
||||||
|
#ifdef GPROF
|
||||||
|
/*
|
||||||
|
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
|
||||||
|
* over the mcounting.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; jmp 2f
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; 2:
|
||||||
|
/*
|
||||||
|
* The call to mcount supports the usual (bad) conventions. We allocate
|
||||||
|
* some data and pass a pointer to it although the 386BSD doesn't use
|
||||||
|
* the data. We set up a frame before calling mcount because that is
|
||||||
|
* the standard convention although it makes work for both mcount and
|
||||||
|
* callers.
|
||||||
|
*/
|
||||||
|
#define MCOUNT .data; ALIGN_DATA; 1:; .long 0; .text; \
|
||||||
|
pushl %ebp; movl %esp, %ebp; \
|
||||||
|
movl $1b,%eax; call mcount; popl %ebp
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* ALTENTRY() has to align because it is before a corresponding ENTRY().
|
||||||
|
* ENTRY() has to align to because there may be no ALTENTRY() before it.
|
||||||
|
* If there is a previous ALTENTRY() then the alignment code is empty.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
||||||
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
||||||
@ -143,10 +169,11 @@
|
|||||||
.globl _boothowto, _bootdev, _curpcb
|
.globl _boothowto, _bootdev, _curpcb
|
||||||
.globl __ucodesel,__udatasel
|
.globl __ucodesel,__udatasel
|
||||||
|
|
||||||
.globl _cpu, _cold, _atdevbase, _atdevphys
|
.globl _cpu, _cold, _atdevbase
|
||||||
_cpu: .long 0 # are we 386, 386sx, or 486
|
_cpu: .long 0 # are we 386, 386sx, or 486
|
||||||
_cold: .long 1 # cold till we are not
|
_cold: .long 1 # cold till we are not
|
||||||
_atdevbase: .long 0 # location of start of iomem in virtual
|
_atdevbase: .long 0 # location of start of iomem in virtual
|
||||||
|
# .nonglobl _atdevphys (should be register or something)
|
||||||
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
||||||
|
|
||||||
.globl _IdlePTD, _KPTphys
|
.globl _IdlePTD, _KPTphys
|
||||||
@ -158,7 +185,8 @@ _cyloffset: .long 0
|
|||||||
_proc0paddr: .long 0
|
_proc0paddr: .long 0
|
||||||
|
|
||||||
#ifdef SHOW_A_LOT
|
#ifdef SHOW_A_LOT
|
||||||
bit_colors: .byte GREEN,RED,0,0
|
bit_colors:
|
||||||
|
.byte GREEN,RED,0,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.space 512
|
.space 512
|
||||||
@ -171,11 +199,11 @@ tmpstk:
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* start: jumped to directly from the boot blocks
|
* btext: beginning of text section.
|
||||||
|
* Also the entry point (jumped to directly from the boot blocks).
|
||||||
*/
|
*/
|
||||||
LENTRY(start)
|
ENTRY(btext)
|
||||||
movw $0x1234,%ax
|
movw $0x1234, 0x472 # warm boot
|
||||||
movw %ax,0x472 # warm boot
|
|
||||||
jmp 1f
|
jmp 1f
|
||||||
.space 0x500 # skip over warm boot shit
|
.space 0x500 # skip over warm boot shit
|
||||||
|
|
||||||
@ -278,7 +306,10 @@ LENTRY(start)
|
|||||||
movl %esi,%ecx # this much memory,
|
movl %esi,%ecx # this much memory,
|
||||||
shrl $ PGSHIFT,%ecx # for this many pte s
|
shrl $ PGSHIFT,%ecx # for this many pte s
|
||||||
addl $ UPAGES+4,%ecx # including our early context
|
addl $ UPAGES+4,%ecx # including our early context
|
||||||
movl $0xa0,%ecx # XXX - cover debugger pages
|
cmpl $0xa0,%ecx # XXX - cover debugger pages
|
||||||
|
jae 1f
|
||||||
|
movl $0xa0,%ecx
|
||||||
|
1:
|
||||||
movl $PG_V|PG_KW,%eax # having these bits set,
|
movl $PG_V|PG_KW,%eax # having these bits set,
|
||||||
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
||||||
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
||||||
@ -372,9 +403,15 @@ LENTRY(start)
|
|||||||
|
|
||||||
/* load base of page directory, and enable mapping */
|
/* load base of page directory, and enable mapping */
|
||||||
movl %esi,%eax # phys address of ptd in proc 0
|
movl %esi,%eax # phys address of ptd in proc 0
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3 # load ptd addr into mmu
|
movl %eax,%cr3 # load ptd addr into mmu
|
||||||
movl %cr0,%eax # get control word
|
movl %cr0,%eax # get control word
|
||||||
|
/*
|
||||||
|
* XXX it is now safe to always (attempt to) set CR0_WP and to set up
|
||||||
|
* the page tables assuming it works, so USE_486_WRITE_PROTECT will go
|
||||||
|
* away. The special 386 PTE checking needs to be conditional on
|
||||||
|
* whatever distingiushes 486-only kernels from 386-486 kernels.
|
||||||
|
*/
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
#ifdef USE_486_WRITE_PROTECT
|
||||||
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
||||||
#else
|
#else
|
||||||
@ -407,7 +444,7 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
|
|||||||
|
|
||||||
lea 7*NBPG(%esi),%esi # skip past stack.
|
lea 7*NBPG(%esi),%esi # skip past stack.
|
||||||
pushl %esi
|
pushl %esi
|
||||||
|
|
||||||
/* relocate debugger gdt entries */
|
/* relocate debugger gdt entries */
|
||||||
|
|
||||||
movl $_gdt+8*9,%eax # adjust slots 9-17
|
movl $_gdt+8*9,%eax # adjust slots 9-17
|
||||||
@ -423,9 +460,9 @@ reloc_gdt:
|
|||||||
1:
|
1:
|
||||||
|
|
||||||
call _init386 # wire 386 chip for unix operation
|
call _init386 # wire 386 chip for unix operation
|
||||||
|
|
||||||
movl $0,_PTD
|
movl $0,_PTD
|
||||||
call _main # autoconfiguration, mountroot etc
|
call _main # autoconfiguration, mountroot etc
|
||||||
popl %esi
|
popl %esi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -459,9 +496,11 @@ lretmsg1:
|
|||||||
/*
|
/*
|
||||||
* Icode is copied out to process 1 and executed in user mode:
|
* Icode is copied out to process 1 and executed in user mode:
|
||||||
* execve("/sbin/init", argv, envp); exit(0);
|
* execve("/sbin/init", argv, envp); exit(0);
|
||||||
* If the exec fails, process 1 exits and the system panics.
|
* If the execve fails, process 1 exits and the system panics.
|
||||||
*/
|
*/
|
||||||
ENTRY(icode)
|
NON_GPROF_ENTRY(icode)
|
||||||
|
pushl $0 # envp
|
||||||
|
|
||||||
# pushl $argv-_icode # gas fucks up again
|
# pushl $argv-_icode # gas fucks up again
|
||||||
movl $argv,%eax
|
movl $argv,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
@ -471,14 +510,17 @@ ENTRY(icode)
|
|||||||
movl $init,%eax
|
movl $init,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
pushl %eax
|
pushl %eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
|
|
||||||
movl %esp,%ebp
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exec,%eax
|
movl $exec,%eax
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
pushl %eax
|
|
||||||
|
pushl %eax # execve failed, the errno will do for an
|
||||||
|
# exit code because errnos are < 128
|
||||||
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exit,%eax
|
movl $exit,%eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@ -494,7 +536,7 @@ eicode:
|
|||||||
_szicode:
|
_szicode:
|
||||||
.long _szicode-_icode
|
.long _szicode-_icode
|
||||||
|
|
||||||
ENTRY(sigcode)
|
NON_GPROF_ENTRY(sigcode)
|
||||||
call 12(%esp)
|
call 12(%esp)
|
||||||
lea 28(%esp),%eax # scp (the call may have clobbered the
|
lea 28(%esp),%eax # scp (the call may have clobbered the
|
||||||
# copy at 8(%esp))
|
# copy at 8(%esp))
|
||||||
@ -640,7 +682,7 @@ ENTRY(bzero) # void bzero(void *base, u_int cnt)
|
|||||||
movl 8(%esp),%edi
|
movl 8(%esp),%edi
|
||||||
movl 12(%esp),%ecx
|
movl 12(%esp),%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
shrl $2,%ecx
|
shrl $2,%ecx
|
||||||
cld
|
cld
|
||||||
rep
|
rep
|
||||||
stosl
|
stosl
|
||||||
@ -664,6 +706,7 @@ ENTRY(fillw) # fillw (pat,base,cnt)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyb)
|
ENTRY(bcopyb)
|
||||||
|
bcopyb:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -672,7 +715,7 @@ ENTRY(bcopyb)
|
|||||||
cmpl %esi,%edi /* potentially overlapping? */
|
cmpl %esi,%edi /* potentially overlapping? */
|
||||||
jnb 1f
|
jnb 1f
|
||||||
cld /* nope, copy forwards */
|
cld /* nope, copy forwards */
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -693,6 +736,7 @@ ENTRY(bcopyb)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyw)
|
ENTRY(bcopyw)
|
||||||
|
bcopyw:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -735,20 +779,18 @@ ENTRY(bcopyw)
|
|||||||
ENTRY(bcopyx)
|
ENTRY(bcopyx)
|
||||||
movl 16(%esp),%eax
|
movl 16(%esp),%eax
|
||||||
cmpl $2,%eax
|
cmpl $2,%eax
|
||||||
je _bcopyw
|
je bcopyw /* not _bcopyw, to avoid multiple mcounts */
|
||||||
cmpl $4,%eax
|
cmpl $4,%eax
|
||||||
jne _bcopyb
|
je bcopy
|
||||||
/*
|
jmp bcopyb
|
||||||
* Fall through to bcopy. ENTRY() provides harmless fill bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (ov)bcopy (src,dst,cnt)
|
* (ov)bcopy (src,dst,cnt)
|
||||||
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
||||||
*/
|
*/
|
||||||
ENTRY(bcopy)
|
|
||||||
ALTENTRY(ovbcopy)
|
ALTENTRY(ovbcopy)
|
||||||
|
ENTRY(bcopy)
|
||||||
|
bcopy:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -789,8 +831,8 @@ ALTENTRY(ovbcopy)
|
|||||||
cld
|
cld
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohl)
|
ALTENTRY(ntohl)
|
||||||
ALTENTRY(htonl)
|
ENTRY(htonl)
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
#ifdef i486
|
#ifdef i486
|
||||||
/* XXX */
|
/* XXX */
|
||||||
@ -798,7 +840,7 @@ ALTENTRY(htonl)
|
|||||||
* equivalent bytes. This can be changed back to bswap when we
|
* equivalent bytes. This can be changed back to bswap when we
|
||||||
* upgrade to a newer version of Gas */
|
* upgrade to a newer version of Gas */
|
||||||
/* bswap %eax */
|
/* bswap %eax */
|
||||||
.byte 0x0f
|
.byte 0x0f
|
||||||
.byte 0xc8
|
.byte 0xc8
|
||||||
#else
|
#else
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
@ -807,8 +849,8 @@ ALTENTRY(htonl)
|
|||||||
#endif
|
#endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohs)
|
ALTENTRY(ntohs)
|
||||||
ALTENTRY(htons)
|
ENTRY(htons)
|
||||||
movzwl 4(%esp),%eax
|
movzwl 4(%esp),%eax
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
ret
|
ret
|
||||||
@ -861,10 +903,6 @@ show_bits:
|
|||||||
* protection violation occurs inside the functions, the trap handler
|
* protection violation occurs inside the functions, the trap handler
|
||||||
* returns to *curpcb->onfault instead of the function.
|
* returns to *curpcb->onfault instead of the function.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* XXX These routines load a segment register every time they execute.
|
|
||||||
* it would be nicer (faster) if they could depend on %gs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
||||||
@ -879,15 +917,36 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
orl %ebx, %ebx # nothing to do?
|
orl %ebx, %ebx # nothing to do?
|
||||||
jz done_copyout
|
jz done_copyout
|
||||||
|
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
/*
|
||||||
/* if WP bit in CR0 is set (n/a on 386), the hardware does the */
|
* Check explicitly for non-user addresses. If 486 write protection
|
||||||
/* write check. We just have to load the right segment selector */
|
* is being used, this check is essential because we are in kernel
|
||||||
pushl %es
|
* mode so the h/w does not provide any protection against writing
|
||||||
movl __udatasel, %eax
|
* kernel addresses.
|
||||||
movl %ax, %es
|
*
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
* Otherwise, it saves having to load and restore %es to get the
|
||||||
/* we have to check each PTE for (write) permission */
|
* usual segment-based protection (the destination segment for movs
|
||||||
|
* is always %es). The other explicit checks for user-writablility
|
||||||
|
* are not quite sufficient. They fail for the user area because
|
||||||
|
* we mapped the user area read/write to avoid having an #ifdef in
|
||||||
|
* vm_machdep.c. They fail for user PTEs and/or PTDs! (107
|
||||||
|
* addresses including 0xff800000 and 0xfc000000). I'm not sure if
|
||||||
|
* this can be fixed. Marking the PTEs supervisor mode and the
|
||||||
|
* PDE's user mode would almost work, but there may be a problem
|
||||||
|
* with the self-referential PDE.
|
||||||
|
*/
|
||||||
|
movl %edi, %eax
|
||||||
|
addl %ebx, %eax
|
||||||
|
jc copyout_fault
|
||||||
|
#define VM_END_USER_ADDRESS 0xFDBFE000 /* XXX */
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %eax
|
||||||
|
ja copyout_fault
|
||||||
|
|
||||||
|
#ifndef USE_486_WRITE_PROTECT
|
||||||
|
/*
|
||||||
|
* We have to check each PTE for user write permission.
|
||||||
|
* The checking may cause a page fault, so it is important to set
|
||||||
|
* up everything for return via copyout_fault before here.
|
||||||
|
*/
|
||||||
/* compute number of pages */
|
/* compute number of pages */
|
||||||
movl %edi, %ecx
|
movl %edi, %ecx
|
||||||
andl $0x0fff, %ecx
|
andl $0x0fff, %ecx
|
||||||
@ -906,7 +965,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
||||||
cmpb $0x07, %al
|
cmpb $0x07, %al
|
||||||
je 2f
|
je 2f
|
||||||
|
|
||||||
/* simulate a trap */
|
/* simulate a trap */
|
||||||
pushl %edx
|
pushl %edx
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
@ -924,8 +983,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
addl $4, %edx
|
addl $4, %edx
|
||||||
decl %ecx
|
decl %ecx
|
||||||
jnz 1b /* check next page */
|
jnz 1b /* check next page */
|
||||||
|
#endif /* ndef USE_486_WRITE_PROTECT */
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
|
||||||
|
|
||||||
/* now copy it over */
|
/* now copy it over */
|
||||||
/* bcopy (%esi, %edi, %ebx) */
|
/* bcopy (%esi, %edi, %ebx) */
|
||||||
@ -938,9 +996,6 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $3, %cl
|
andb $3, %cl
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
|
|
||||||
done_copyout:
|
done_copyout:
|
||||||
popl %ebx
|
popl %ebx
|
||||||
@ -951,10 +1006,8 @@ done_copyout:
|
|||||||
movl %eax,PCB_ONFAULT(%edx)
|
movl %eax,PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyout_fault:
|
copyout_fault:
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
popl %ebx
|
popl %ebx
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -972,22 +1025,19 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl 12(%esp),%esi # caddr_t from
|
movl 12(%esp),%esi # caddr_t from
|
||||||
movl 16(%esp),%edi # caddr_t to
|
movl 16(%esp),%edi # caddr_t to
|
||||||
movl 20(%esp),%ecx # size_t len
|
movl 20(%esp),%ecx # size_t len
|
||||||
movl %ecx,%edx
|
|
||||||
pushl %ds
|
|
||||||
movl __udatasel,%ax # access 'from' via user data segment
|
|
||||||
movl %ax,%ds
|
|
||||||
|
|
||||||
movb %cl,%al
|
movb %cl,%al
|
||||||
shrl $2,%ecx # copy longword-wise
|
shrl $2,%ecx # copy longword-wise
|
||||||
cld
|
cld
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsl
|
movsl
|
||||||
movb %al,%cl
|
movb %al,%cl
|
||||||
andb $3,%cl # copy remaining bytes
|
andb $3,%cl # copy remaining bytes
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
|
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
@ -995,8 +1045,8 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl %eax, PCB_ONFAULT(%edx)
|
movl %eax, PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyin_fault:
|
copyin_fault:
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
movl _curpcb, %edx
|
movl _curpcb, %edx
|
||||||
@ -1007,10 +1057,8 @@ copyin_fault:
|
|||||||
/*
|
/*
|
||||||
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
||||||
*/
|
*/
|
||||||
ENTRY(fuword)
|
|
||||||
ALTENTRY(fuiword)
|
ALTENTRY(fuiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(fuword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1018,10 +1066,8 @@ ALTENTRY(fuiword)
|
|||||||
movl (%edx),%eax
|
movl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fusword)
|
ENTRY(fusword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1029,11 +1075,9 @@ ENTRY(fusword)
|
|||||||
movzwl (%edx),%eax
|
movzwl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fubyte)
|
|
||||||
ALTENTRY(fuibyte)
|
ALTENTRY(fuibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(fubyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1041,7 +1085,8 @@ ALTENTRY(fuibyte)
|
|||||||
movzbl (%edx),%eax
|
movzbl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
fusufault:
|
fusufault:
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
@ -1056,42 +1101,39 @@ fusufault:
|
|||||||
/*
|
/*
|
||||||
* we only have to set the right segment selector.
|
* we only have to set the right segment selector.
|
||||||
*/
|
*/
|
||||||
ENTRY(suword)
|
|
||||||
ALTENTRY(suiword)
|
ALTENTRY(suiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(suword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movl 8(%esp),%eax
|
movl 8(%esp),%eax
|
||||||
gs
|
gs
|
||||||
movl %eax,(%edx)
|
movl %eax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(susword)
|
ENTRY(susword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movw 8(%esp),%ax
|
movw 8(%esp),%ax
|
||||||
gs
|
gs
|
||||||
movw %ax,(%edx)
|
movw %ax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(subyte)
|
|
||||||
ALTENTRY(suibyte)
|
ALTENTRY(suibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(subyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movb 8(%esp),%al
|
movb 8(%esp),%al
|
||||||
gs
|
gs
|
||||||
movb %al,(%edx)
|
movb %al,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -1102,8 +1144,8 @@ ALTENTRY(suibyte)
|
|||||||
*/
|
*/
|
||||||
# XXX - page boundary crossing is not handled yet
|
# XXX - page boundary crossing is not handled yet
|
||||||
|
|
||||||
|
ALTENTRY(suibyte)
|
||||||
ENTRY(subyte)
|
ENTRY(subyte)
|
||||||
ENTRY(suibyte)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1123,6 +1165,7 @@ ENTRY(suibyte)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movb %al, (%edx)
|
movb %al, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1149,14 +1192,15 @@ ENTRY(susword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movw %ax, (%edx)
|
movw %ax, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl %eax, PCB_ONFAULT(%ecx)
|
movl %eax, PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALTENTRY(suiword)
|
||||||
ENTRY(suword)
|
ENTRY(suword)
|
||||||
ENTRY(suiword)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1176,6 +1220,7 @@ ENTRY(suiword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movl %eax, 0(%edx)
|
movl %eax, 0(%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1183,6 +1228,7 @@ ENTRY(suiword)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* copyoutstr(from, to, maxlen, int *lencopied)
|
* copyoutstr(from, to, maxlen, int *lencopied)
|
||||||
* copy a string from from to to, stop when a 0 character is reached.
|
* copy a string from from to to, stop when a 0 character is reached.
|
||||||
@ -1201,13 +1247,19 @@ ENTRY(copyoutstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
decl %edx
|
decl %edx
|
||||||
jz 4f
|
jz 4f
|
||||||
|
/*
|
||||||
|
* gs override doesn't work for stosb. Use the same explicit check
|
||||||
|
* as in copyout(). It's much slower now because it is per-char.
|
||||||
|
* XXX - however, it would be faster to rewrite this function to use
|
||||||
|
* strlen() and copyout().
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
lodsb
|
lodsb
|
||||||
gs
|
gs
|
||||||
stosb
|
stosb
|
||||||
@ -1222,7 +1274,7 @@ ENTRY(copyoutstr)
|
|||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
#else /* ndef USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
ENTRY(copyoutstr)
|
ENTRY(copyoutstr)
|
||||||
pushl %esi
|
pushl %esi
|
||||||
@ -1234,6 +1286,13 @@ ENTRY(copyoutstr)
|
|||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
1:
|
1:
|
||||||
|
/*
|
||||||
|
* It suffices to check that the first byte is in user space, because
|
||||||
|
* we look at a page at a time and the end address is on a page
|
||||||
|
* boundary.
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
movl %edi, %eax
|
movl %edi, %eax
|
||||||
shrl $IDXSHIFT, %eax
|
shrl $IDXSHIFT, %eax
|
||||||
andb $0xfc, %al
|
andb $0xfc, %al
|
||||||
@ -1280,6 +1339,7 @@ ENTRY(copyoutstr)
|
|||||||
/* edx is zero -- return ENAMETOOLONG */
|
/* edx is zero -- return ENAMETOOLONG */
|
||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1298,8 +1358,6 @@ ENTRY(copyinstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
@ -1447,13 +1505,12 @@ ENTRY(ssdtosd) # ssdtosd(*ssdp,*sdp)
|
|||||||
|
|
||||||
ENTRY(tlbflush) # tlbflush()
|
ENTRY(tlbflush) # tlbflush()
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
ENTRY(lcr0) # lcr0(cr0)
|
ENTRY(load_cr0) # load_cr0(cr0)
|
||||||
ALTENTRY(load_cr0)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
movl %eax,%cr0
|
movl %eax,%cr0
|
||||||
ret
|
ret
|
||||||
@ -1470,18 +1527,13 @@ ENTRY(rcr2) # rcr2()
|
|||||||
|
|
||||||
|
|
||||||
ENTRY(rcr3) # rcr3()
|
ENTRY(rcr3) # rcr3()
|
||||||
ALTENTRY(_cr3)
|
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
/*
|
ENTRY(load_cr3) # void load_cr3(caddr_t cr3)
|
||||||
* void lcr3(caddr_t cr3)
|
|
||||||
*/
|
|
||||||
ENTRY(lcr3)
|
|
||||||
ALTENTRY(load_cr3)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1600,17 +1652,19 @@ sw0: .asciz "swtch"
|
|||||||
* When no processes are on the runq, Swtch branches to idle
|
* When no processes are on the runq, Swtch branches to idle
|
||||||
* to wait for something to come ready.
|
* to wait for something to come ready.
|
||||||
*/
|
*/
|
||||||
LENTRY(Idle)
|
ALIGN_TEXT
|
||||||
|
Idle:
|
||||||
sti
|
sti
|
||||||
SHOW_STI
|
SHOW_STI
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
idle_loop:
|
idle_loop:
|
||||||
call _spl0
|
call _spl0
|
||||||
cmpl $0,_whichqs
|
cmpl $0,_whichqs
|
||||||
jne sw1
|
jne sw1
|
||||||
hlt # wait for interrupt
|
hlt # wait for interrupt
|
||||||
jmp idle_loop
|
jmp idle_loop
|
||||||
|
|
||||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
|
||||||
badsw:
|
badsw:
|
||||||
pushl $sw0
|
pushl $sw0
|
||||||
call _panic
|
call _panic
|
||||||
@ -1619,6 +1673,7 @@ badsw:
|
|||||||
/*
|
/*
|
||||||
* Swtch()
|
* Swtch()
|
||||||
*/
|
*/
|
||||||
|
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||||
ENTRY(swtch)
|
ENTRY(swtch)
|
||||||
|
|
||||||
incl _cnt+V_SWTCH
|
incl _cnt+V_SWTCH
|
||||||
@ -1780,7 +1835,7 @@ ENTRY(savectx)
|
|||||||
movl 4(%esp), %ecx
|
movl 4(%esp), %ecx
|
||||||
movw _cpl, %ax
|
movw _cpl, %ax
|
||||||
movw %ax, PCB_IML(%ecx)
|
movw %ax, PCB_IML(%ecx)
|
||||||
movl (%esp), %eax
|
movl (%esp), %eax
|
||||||
movl %eax, PCB_EIP(%ecx)
|
movl %eax, PCB_EIP(%ecx)
|
||||||
movl %ebx, PCB_EBX(%ecx)
|
movl %ebx, PCB_EBX(%ecx)
|
||||||
movl %esp, PCB_ESP(%ecx)
|
movl %esp, PCB_ESP(%ecx)
|
||||||
@ -1885,7 +1940,7 @@ L1:
|
|||||||
proffault:
|
proffault:
|
||||||
/* if we get a fault, then kill profiling all together */
|
/* if we get a fault, then kill profiling all together */
|
||||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||||
movl 12(%ebp),%ecx
|
movl 12(%ebp),%ecx
|
||||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
@ -1903,7 +1958,7 @@ ENTRY(astoff)
|
|||||||
*
|
*
|
||||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||||
*/
|
*/
|
||||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||||
#ifdef KGDB
|
#ifdef KGDB
|
||||||
@ -2048,14 +2103,14 @@ bpttraps:
|
|||||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
||||||
# non-kernel mode?
|
# non-kernel mode?
|
||||||
jne calltrap # yes
|
jne calltrap # yes
|
||||||
call _kgdb_trap_glue
|
call _kgdb_trap_glue
|
||||||
jmp calltrap
|
jmp calltrap
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call gate entry for syscall
|
* Call gate entry for syscall
|
||||||
*/
|
*/
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
IDTVEC(syscall)
|
IDTVEC(syscall)
|
||||||
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
||||||
# XXX - also for direction flag (bzero, etc. clear it)
|
# XXX - also for direction flag (bzero, etc. clear it)
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
* 20 Apr 93 Bruce Evans New npx-0.5 code
|
* 20 Apr 93 Bruce Evans New npx-0.5 code
|
||||||
* 25 Apr 93 Bruce Evans New intr-0.1 code
|
* 25 Apr 93 Bruce Evans New intr-0.1 code
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/i386/i386/machdep.c,v 1.3 1993/07/16 20:50:42 davidg Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/machdep.c,v 1.4 1993/07/16 23:55:07 davidg Exp $";
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -849,16 +849,41 @@ init386(first)
|
|||||||
* Initialize the console before we print anything out.
|
* Initialize the console before we print anything out.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cninit (KERNBASE+0xa0000);
|
cninit ();
|
||||||
|
|
||||||
/* make gdt memory segments */
|
/* make gdt memory segments */
|
||||||
gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
|
gdt_segs[GCODE_SEL].ssd_limit = i386_btop(i386_round_page(&etext)) - 1;
|
||||||
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, &gdt[x][0]);
|
/*
|
||||||
|
* XXX - VM_MAX_KERNEL_ADDRESS is correctly a max, but bogusly the
|
||||||
|
* address of the last page, not the last byte. Then above the end
|
||||||
|
* :-) there is another 4M of page tables or something.
|
||||||
|
*/
|
||||||
|
#define VM_END_KERNEL_ADDRESS (VM_MAX_KERNEL_ADDRESS + NBPG + NBPDR)
|
||||||
|
gdt_segs[GDATA_SEL].ssd_limit = i386_btop(VM_END_KERNEL_ADDRESS) - 1;
|
||||||
|
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
|
||||||
/* make ldt memory segments */
|
/* make ldt memory segments */
|
||||||
ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
|
/*
|
||||||
ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
|
* The data segment limit must not cover the user area because we
|
||||||
|
* don't want the user area to be writable in copyout() etc. (page
|
||||||
|
* level protection is lost in kernel mode on 386's). Also, we
|
||||||
|
* don't want the user area to be writable directly (page level
|
||||||
|
* protection of the user area is not available on 486's with
|
||||||
|
* CR0_WP set, because there is no user-read/kernel-write mode).
|
||||||
|
*
|
||||||
|
* XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it
|
||||||
|
* should be spelled ...MAX_USER...
|
||||||
|
*/
|
||||||
|
#define VM_END_USER_RW_ADDRESS VM_MAXUSER_ADDRESS
|
||||||
|
/*
|
||||||
|
* The code segment limit has to cover the user area until we move
|
||||||
|
* the signal trampoline out of the user area. This is safe because
|
||||||
|
* the code segment cannot be written to directly.
|
||||||
|
*/
|
||||||
|
#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
|
||||||
|
ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
|
||||||
|
ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
|
||||||
/* Note. eventually want private ldts per process */
|
/* Note. eventually want private ldts per process */
|
||||||
for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, &ldt[x][0]);
|
for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
|
||||||
|
|
||||||
/* exceptions */
|
/* exceptions */
|
||||||
setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
|
setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
|
||||||
@ -951,7 +976,8 @@ init386(first)
|
|||||||
Maxmem = 640/4;
|
Maxmem = 640/4;
|
||||||
else {
|
else {
|
||||||
Maxmem = pagesinext + 0x100000/NBPG;
|
Maxmem = pagesinext + 0x100000/NBPG;
|
||||||
first = 0x100000; /* skip hole */
|
if (first < 0x100000)
|
||||||
|
first = 0x100000; /* skip hole */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This used to explode, since Maxmem used to be 0 for bas CMOS*/
|
/* This used to explode, since Maxmem used to be 0 for bas CMOS*/
|
||||||
@ -1077,6 +1103,7 @@ _remque(element)
|
|||||||
element->ph_rlink = (struct proc *)0;
|
element->ph_rlink = (struct proc *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SLOW_OLD_COPYSTRS
|
||||||
vmunaccess() {}
|
vmunaccess() {}
|
||||||
|
|
||||||
#if 0 /* assembler versions now in locore.s */
|
#if 0 /* assembler versions now in locore.s */
|
||||||
@ -1124,6 +1151,8 @@ copyoutstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
|||||||
return(ENAMETOOLONG);
|
return(ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* SLOW_OLD_COPYSTRS */
|
||||||
|
|
||||||
copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
||||||
void *fromaddr, *toaddr; {
|
void *fromaddr, *toaddr; {
|
||||||
u_int tally;
|
u_int tally;
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
*
|
*
|
||||||
* 28 Nov 1991 Poul-Henning Kamp Speedup processing.
|
* 28 Nov 1991 Poul-Henning Kamp Speedup processing.
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /usr/src/sys.386bsd/i386/i386/RCS/pmap.c,v 1.3 92/01/21 14:26:44 william Exp Locker: root $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/pmap.c,v 1.1.1.1 1993/06/12 14:58:06 rgrimes Exp $";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Derived from hp300 version by Mike Hibler, this version by William
|
* Derived from hp300 version by Mike Hibler, this version by William
|
||||||
@ -461,7 +461,7 @@ pmap_pinit(pmap)
|
|||||||
|
|
||||||
/* install self-referential address mapping entry */
|
/* install self-referential address mapping entry */
|
||||||
*(int *)(pmap->pm_pdir+PTDPTDI) =
|
*(int *)(pmap->pm_pdir+PTDPTDI) =
|
||||||
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_URKW;
|
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_KW;
|
||||||
|
|
||||||
pmap->pm_count = 1;
|
pmap->pm_count = 1;
|
||||||
simple_lock_init(&pmap->pm_lock);
|
simple_lock_init(&pmap->pm_lock);
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
* 08 Apr 93 Bruce Evans Several VM system fixes
|
* 08 Apr 93 Bruce Evans Several VM system fixes
|
||||||
* Paul Kranenburg Add counter for vmstat
|
* Paul Kranenburg Add counter for vmstat
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2 92/01/21 14:22:13 william Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/trap.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 386 Trap and System call handleing
|
* 386 Trap and System call handleing
|
||||||
@ -70,6 +70,21 @@ static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2
|
|||||||
|
|
||||||
#include "machine/trap.h"
|
#include "machine/trap.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
|
||||||
|
* we omit the size from the mov instruction to avoid nonfatal bugs in gas.
|
||||||
|
*/
|
||||||
|
#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
|
||||||
|
#define write_gs(gs) __asm("mov %0,%%gs" : : "r" ((u_short) gs))
|
||||||
|
|
||||||
|
#else /* not __GNUC__ */
|
||||||
|
|
||||||
|
u_short read_gs __P((void));
|
||||||
|
void write_gs __P((/* promoted u_short */ int gs));
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
struct sysent sysent[];
|
struct sysent sysent[];
|
||||||
int nsysent;
|
int nsysent;
|
||||||
@ -112,9 +127,25 @@ trap(frame)
|
|||||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||||
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
||||||
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||||
if (curpcb->pcb_onfault && frame.tf_trapno != 0xc) {
|
if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) {
|
||||||
|
extern int _udatasel;
|
||||||
|
|
||||||
|
if (read_gs() != (u_short) _udatasel)
|
||||||
|
/*
|
||||||
|
* Some user has corrupted %gs but we depend on it in
|
||||||
|
* copyout() etc. Fix it up and retry.
|
||||||
|
*
|
||||||
|
* (We don't preserve %fs or %gs, so users can change
|
||||||
|
* them to either _ucodesel, _udatasel or a not-present
|
||||||
|
* selector, possibly ORed with 0 to 3, making them
|
||||||
|
* volatile for other users. Not preserving them saves
|
||||||
|
* time and doesn't lose functionality or open security
|
||||||
|
* holes.)
|
||||||
|
*/
|
||||||
|
write_gs(_udatasel);
|
||||||
|
else
|
||||||
copyfault:
|
copyfault:
|
||||||
frame.tf_eip = (int)curpcb->pcb_onfault;
|
frame.tf_eip = (int)curpcb->pcb_onfault;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,18 +427,49 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensate for 386 brain damage (missing URKR)
|
* Compensate for 386 brain damage (missing URKR).
|
||||||
|
* This is a little simpler than the pagefault handler in trap() because
|
||||||
|
* it the page tables have already been faulted in and high addresses
|
||||||
|
* are thrown out early for other reasons.
|
||||||
*/
|
*/
|
||||||
int trapwrite(unsigned addr) {
|
int trapwrite(addr)
|
||||||
int rv;
|
unsigned addr;
|
||||||
|
{
|
||||||
|
unsigned nss;
|
||||||
|
struct proc *p;
|
||||||
vm_offset_t va;
|
vm_offset_t va;
|
||||||
|
struct vmspace *vm;
|
||||||
|
|
||||||
va = trunc_page((vm_offset_t)addr);
|
va = trunc_page((vm_offset_t)addr);
|
||||||
if (va > VM_MAXUSER_ADDRESS) return(1);
|
/*
|
||||||
rv = vm_fault(&curproc->p_vmspace->vm_map, va,
|
* XXX - MAX is END. Changed > to >= for temp. fix.
|
||||||
VM_PROT_READ | VM_PROT_WRITE, FALSE);
|
*/
|
||||||
if (rv == KERN_SUCCESS) return(0);
|
if (va >= VM_MAXUSER_ADDRESS)
|
||||||
else return(1);
|
return (1);
|
||||||
|
/*
|
||||||
|
* XXX: rude stack hack adapted from trap().
|
||||||
|
*/
|
||||||
|
nss = 0;
|
||||||
|
p = curproc;
|
||||||
|
vm = p->p_vmspace;
|
||||||
|
if ((caddr_t)va >= vm->vm_maxsaddr && dostacklimits) {
|
||||||
|
nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ
|
||||||
|
- (unsigned)va));
|
||||||
|
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE)
|
||||||
|
!= KERN_SUCCESS)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: continuation of rude stack hack
|
||||||
|
*/
|
||||||
|
if (nss > vm->vm_ssize)
|
||||||
|
vm->vm_ssize = nss;
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
/*
|
/*
|
||||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/i386/i386/vm_machdep.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/vm_machdep.c,v 1.2 1993/07/18 20:56:17 paul Exp $";
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include "systm.h"
|
#include "systm.h"
|
||||||
@ -105,8 +105,15 @@ cpu_fork(p1, p2)
|
|||||||
vm_map_pageable(&p2->p_vmspace->vm_map, addr, addr+NBPG, FALSE);
|
vm_map_pageable(&p2->p_vmspace->vm_map, addr, addr+NBPG, FALSE);
|
||||||
for (i=0; i < UPAGES; i++)
|
for (i=0; i < UPAGES; i++)
|
||||||
pmap_enter(&p2->p_vmspace->vm_pmap, kstack+i*NBPG,
|
pmap_enter(&p2->p_vmspace->vm_pmap, kstack+i*NBPG,
|
||||||
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG), VM_PROT_READ, 1);
|
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG),
|
||||||
|
/*
|
||||||
|
* The user area has to be mapped writable because
|
||||||
|
* it contains the kernel stack (when CR0_WP is on
|
||||||
|
* on a 486 there is no user-read/kernel-write
|
||||||
|
* mode). It is protected from user mode access
|
||||||
|
* by the segment limits.
|
||||||
|
*/
|
||||||
|
VM_PROT_READ|VM_PROT_WRITE, TRUE);
|
||||||
pmap_activate(&p2->p_vmspace->vm_pmap, &up->u_pcb);
|
pmap_activate(&p2->p_vmspace->vm_pmap, &up->u_pcb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -53,10 +53,12 @@
|
|||||||
* these are defined to get generic functions
|
* these are defined to get generic functions
|
||||||
* rather than inline or machine-dependent implementations
|
* rather than inline or machine-dependent implementations
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
#define NEED_MINMAX /* need {,i,l,ul}{min,max} functions */
|
#define NEED_MINMAX /* need {,i,l,ul}{min,max} functions */
|
||||||
#define NEED_FFS /* need ffs function */
|
#define NEED_FFS /* need ffs function */
|
||||||
#define NEED_BCMP /* need bcmp function */
|
#define NEED_BCMP /* need bcmp function */
|
||||||
#define NEED_STRLEN /* need strlen function */
|
#define NEED_STRLEN /* need strlen function */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define cpu_exec(p) /* nothing */
|
#define cpu_exec(p) /* nothing */
|
||||||
|
|
||||||
|
@ -58,6 +58,116 @@ outb(u_int port, u_char data)
|
|||||||
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
|
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
imin(a, b)
|
||||||
|
int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
imax(a, b)
|
||||||
|
int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned int
|
||||||
|
min(a, b)
|
||||||
|
unsigned int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned int
|
||||||
|
max(a, b)
|
||||||
|
unsigned int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
long
|
||||||
|
lmin(a, b)
|
||||||
|
long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
long
|
||||||
|
lmax(a, b)
|
||||||
|
long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned long
|
||||||
|
ulmin(a, b)
|
||||||
|
unsigned long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned long
|
||||||
|
ulmax(a, b)
|
||||||
|
unsigned long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
ffs(mask)
|
||||||
|
register long mask;
|
||||||
|
{
|
||||||
|
register int bit;
|
||||||
|
|
||||||
|
if (!mask)
|
||||||
|
return(0);
|
||||||
|
for (bit = 1;; ++bit) {
|
||||||
|
if (mask&0x01)
|
||||||
|
return(bit);
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
bcmp(v1, v2, len)
|
||||||
|
void *v1, *v2;
|
||||||
|
register unsigned len;
|
||||||
|
{
|
||||||
|
register u_char *s1 = v1, *s2 = v2;
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
if (*s1++ != *s2++)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
size_t
|
||||||
|
strlen(s1)
|
||||||
|
register __const__ char *s1;
|
||||||
|
{
|
||||||
|
register size_t len;
|
||||||
|
|
||||||
|
for (len = 0; *s1++ != '\0'; len++)
|
||||||
|
;
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
#else /* not __GNUC__ */
|
#else /* not __GNUC__ */
|
||||||
|
|
||||||
int bdb __P((void));
|
int bdb __P((void));
|
||||||
@ -80,3 +190,4 @@ really_void setidt __P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
|
|||||||
|
|
||||||
#undef really_u_int
|
#undef really_u_int
|
||||||
#undef really_void
|
#undef really_void
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
/*
|
/*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* $Log: db_output.c,v $
|
* $Log: db_output.c,v $
|
||||||
|
* Revision 1.1.1.1 1993/06/12 14:57:37 rgrimes
|
||||||
|
* Initial import, 0.1 + pk 0.2.4-B1
|
||||||
|
*
|
||||||
* Revision 1.1 1992/03/25 21:45:18 pace
|
* Revision 1.1 1992/03/25 21:45:18 pace
|
||||||
* Initial revision
|
* Initial revision
|
||||||
*
|
*
|
||||||
@ -60,6 +63,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "systm.h"
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
* Modification history
|
* Modification history
|
||||||
*
|
*
|
||||||
* $Log: if_ed.c,v $
|
* $Log: if_ed.c,v $
|
||||||
|
* Revision 1.18 93/07/27 03:41:36 davidg
|
||||||
|
* removed unnecessary variable assignment in ed_reset()
|
||||||
|
*
|
||||||
* Revision 1.17 93/07/26 18:40:57 davidg
|
* Revision 1.17 93/07/26 18:40:57 davidg
|
||||||
* Added include of systm.h to pick up inlined min/max/bcmp if you have
|
* Added include of systm.h to pick up inlined min/max/bcmp if you have
|
||||||
* them in cpufunc.h. Modified wait loop in reset to look a little better.
|
* them in cpufunc.h. Modified wait loop in reset to look a little better.
|
||||||
@ -798,7 +801,7 @@ ed_reset(unit)
|
|||||||
ed_stop(unit);
|
ed_stop(unit);
|
||||||
ed_init(unit);
|
ed_init(unit);
|
||||||
|
|
||||||
s = splx(s);
|
(void) splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#if NSPEAKER > 0
|
#if NSPEAKER > 0
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "systm.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
@ -89,9 +89,35 @@
|
|||||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
||||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
||||||
|
|
||||||
#define LENTRY(name) ALIGN_TEXT; .globl name; name:
|
#define GEN_ENTRY(name) ALIGN_TEXT; .globl name; name:
|
||||||
#define ENTRY(name) ALIGN_TEXT; .globl _/**/name; _/**/name:
|
#define NON_GPROF_ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
#define ALTENTRY(name) .globl _/**/name; _/**/name:
|
|
||||||
|
#ifdef GPROF
|
||||||
|
/*
|
||||||
|
* ALTENTRY() must be before a corresponding ENTRY() so that it can jump
|
||||||
|
* over the mcounting.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; jmp 2f
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name); MCOUNT; 2:
|
||||||
|
/*
|
||||||
|
* The call to mcount supports the usual (bad) conventions. We allocate
|
||||||
|
* some data and pass a pointer to it although the 386BSD doesn't use
|
||||||
|
* the data. We set up a frame before calling mcount because that is
|
||||||
|
* the standard convention although it makes work for both mcount and
|
||||||
|
* callers.
|
||||||
|
*/
|
||||||
|
#define MCOUNT .data; ALIGN_DATA; 1:; .long 0; .text; \
|
||||||
|
pushl %ebp; movl %esp, %ebp; \
|
||||||
|
movl $1b,%eax; call mcount; popl %ebp
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* ALTENTRY() has to align because it is before a corresponding ENTRY().
|
||||||
|
* ENTRY() has to align to because there may be no ALTENTRY() before it.
|
||||||
|
* If there is a previous ALTENTRY() then the alignment code is empty.
|
||||||
|
*/
|
||||||
|
#define ALTENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#define ENTRY(name) GEN_ENTRY(_/**/name)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
||||||
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
||||||
@ -143,10 +169,11 @@
|
|||||||
.globl _boothowto, _bootdev, _curpcb
|
.globl _boothowto, _bootdev, _curpcb
|
||||||
.globl __ucodesel,__udatasel
|
.globl __ucodesel,__udatasel
|
||||||
|
|
||||||
.globl _cpu, _cold, _atdevbase, _atdevphys
|
.globl _cpu, _cold, _atdevbase
|
||||||
_cpu: .long 0 # are we 386, 386sx, or 486
|
_cpu: .long 0 # are we 386, 386sx, or 486
|
||||||
_cold: .long 1 # cold till we are not
|
_cold: .long 1 # cold till we are not
|
||||||
_atdevbase: .long 0 # location of start of iomem in virtual
|
_atdevbase: .long 0 # location of start of iomem in virtual
|
||||||
|
# .nonglobl _atdevphys (should be register or something)
|
||||||
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
_atdevphys: .long 0 # location of device mapping ptes (phys)
|
||||||
|
|
||||||
.globl _IdlePTD, _KPTphys
|
.globl _IdlePTD, _KPTphys
|
||||||
@ -158,7 +185,8 @@ _cyloffset: .long 0
|
|||||||
_proc0paddr: .long 0
|
_proc0paddr: .long 0
|
||||||
|
|
||||||
#ifdef SHOW_A_LOT
|
#ifdef SHOW_A_LOT
|
||||||
bit_colors: .byte GREEN,RED,0,0
|
bit_colors:
|
||||||
|
.byte GREEN,RED,0,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.space 512
|
.space 512
|
||||||
@ -171,11 +199,11 @@ tmpstk:
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* start: jumped to directly from the boot blocks
|
* btext: beginning of text section.
|
||||||
|
* Also the entry point (jumped to directly from the boot blocks).
|
||||||
*/
|
*/
|
||||||
LENTRY(start)
|
ENTRY(btext)
|
||||||
movw $0x1234,%ax
|
movw $0x1234, 0x472 # warm boot
|
||||||
movw %ax,0x472 # warm boot
|
|
||||||
jmp 1f
|
jmp 1f
|
||||||
.space 0x500 # skip over warm boot shit
|
.space 0x500 # skip over warm boot shit
|
||||||
|
|
||||||
@ -278,7 +306,10 @@ LENTRY(start)
|
|||||||
movl %esi,%ecx # this much memory,
|
movl %esi,%ecx # this much memory,
|
||||||
shrl $ PGSHIFT,%ecx # for this many pte s
|
shrl $ PGSHIFT,%ecx # for this many pte s
|
||||||
addl $ UPAGES+4,%ecx # including our early context
|
addl $ UPAGES+4,%ecx # including our early context
|
||||||
movl $0xa0,%ecx # XXX - cover debugger pages
|
cmpl $0xa0,%ecx # XXX - cover debugger pages
|
||||||
|
jae 1f
|
||||||
|
movl $0xa0,%ecx
|
||||||
|
1:
|
||||||
movl $PG_V|PG_KW,%eax # having these bits set,
|
movl $PG_V|PG_KW,%eax # having these bits set,
|
||||||
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
|
||||||
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
|
||||||
@ -372,9 +403,15 @@ LENTRY(start)
|
|||||||
|
|
||||||
/* load base of page directory, and enable mapping */
|
/* load base of page directory, and enable mapping */
|
||||||
movl %esi,%eax # phys address of ptd in proc 0
|
movl %esi,%eax # phys address of ptd in proc 0
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3 # load ptd addr into mmu
|
movl %eax,%cr3 # load ptd addr into mmu
|
||||||
movl %cr0,%eax # get control word
|
movl %cr0,%eax # get control word
|
||||||
|
/*
|
||||||
|
* XXX it is now safe to always (attempt to) set CR0_WP and to set up
|
||||||
|
* the page tables assuming it works, so USE_486_WRITE_PROTECT will go
|
||||||
|
* away. The special 386 PTE checking needs to be conditional on
|
||||||
|
* whatever distingiushes 486-only kernels from 386-486 kernels.
|
||||||
|
*/
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
#ifdef USE_486_WRITE_PROTECT
|
||||||
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
|
||||||
#else
|
#else
|
||||||
@ -407,7 +444,7 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
|
|||||||
|
|
||||||
lea 7*NBPG(%esi),%esi # skip past stack.
|
lea 7*NBPG(%esi),%esi # skip past stack.
|
||||||
pushl %esi
|
pushl %esi
|
||||||
|
|
||||||
/* relocate debugger gdt entries */
|
/* relocate debugger gdt entries */
|
||||||
|
|
||||||
movl $_gdt+8*9,%eax # adjust slots 9-17
|
movl $_gdt+8*9,%eax # adjust slots 9-17
|
||||||
@ -423,9 +460,9 @@ reloc_gdt:
|
|||||||
1:
|
1:
|
||||||
|
|
||||||
call _init386 # wire 386 chip for unix operation
|
call _init386 # wire 386 chip for unix operation
|
||||||
|
|
||||||
movl $0,_PTD
|
movl $0,_PTD
|
||||||
call _main # autoconfiguration, mountroot etc
|
call _main # autoconfiguration, mountroot etc
|
||||||
popl %esi
|
popl %esi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -459,9 +496,11 @@ lretmsg1:
|
|||||||
/*
|
/*
|
||||||
* Icode is copied out to process 1 and executed in user mode:
|
* Icode is copied out to process 1 and executed in user mode:
|
||||||
* execve("/sbin/init", argv, envp); exit(0);
|
* execve("/sbin/init", argv, envp); exit(0);
|
||||||
* If the exec fails, process 1 exits and the system panics.
|
* If the execve fails, process 1 exits and the system panics.
|
||||||
*/
|
*/
|
||||||
ENTRY(icode)
|
NON_GPROF_ENTRY(icode)
|
||||||
|
pushl $0 # envp
|
||||||
|
|
||||||
# pushl $argv-_icode # gas fucks up again
|
# pushl $argv-_icode # gas fucks up again
|
||||||
movl $argv,%eax
|
movl $argv,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
@ -471,14 +510,17 @@ ENTRY(icode)
|
|||||||
movl $init,%eax
|
movl $init,%eax
|
||||||
subl $_icode,%eax
|
subl $_icode,%eax
|
||||||
pushl %eax
|
pushl %eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
|
|
||||||
movl %esp,%ebp
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exec,%eax
|
movl $exec,%eax
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
pushl %eax
|
|
||||||
|
pushl %eax # execve failed, the errno will do for an
|
||||||
|
# exit code because errnos are < 128
|
||||||
|
pushl %eax # junk to fake return address
|
||||||
|
|
||||||
movl $exit,%eax
|
movl $exit,%eax
|
||||||
pushl %eax # dummy out rta
|
|
||||||
LCALL(0x7,0x0)
|
LCALL(0x7,0x0)
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@ -494,7 +536,7 @@ eicode:
|
|||||||
_szicode:
|
_szicode:
|
||||||
.long _szicode-_icode
|
.long _szicode-_icode
|
||||||
|
|
||||||
ENTRY(sigcode)
|
NON_GPROF_ENTRY(sigcode)
|
||||||
call 12(%esp)
|
call 12(%esp)
|
||||||
lea 28(%esp),%eax # scp (the call may have clobbered the
|
lea 28(%esp),%eax # scp (the call may have clobbered the
|
||||||
# copy at 8(%esp))
|
# copy at 8(%esp))
|
||||||
@ -640,7 +682,7 @@ ENTRY(bzero) # void bzero(void *base, u_int cnt)
|
|||||||
movl 8(%esp),%edi
|
movl 8(%esp),%edi
|
||||||
movl 12(%esp),%ecx
|
movl 12(%esp),%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
shrl $2,%ecx
|
shrl $2,%ecx
|
||||||
cld
|
cld
|
||||||
rep
|
rep
|
||||||
stosl
|
stosl
|
||||||
@ -664,6 +706,7 @@ ENTRY(fillw) # fillw (pat,base,cnt)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyb)
|
ENTRY(bcopyb)
|
||||||
|
bcopyb:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -672,7 +715,7 @@ ENTRY(bcopyb)
|
|||||||
cmpl %esi,%edi /* potentially overlapping? */
|
cmpl %esi,%edi /* potentially overlapping? */
|
||||||
jnb 1f
|
jnb 1f
|
||||||
cld /* nope, copy forwards */
|
cld /* nope, copy forwards */
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -693,6 +736,7 @@ ENTRY(bcopyb)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(bcopyw)
|
ENTRY(bcopyw)
|
||||||
|
bcopyw:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -735,20 +779,18 @@ ENTRY(bcopyw)
|
|||||||
ENTRY(bcopyx)
|
ENTRY(bcopyx)
|
||||||
movl 16(%esp),%eax
|
movl 16(%esp),%eax
|
||||||
cmpl $2,%eax
|
cmpl $2,%eax
|
||||||
je _bcopyw
|
je bcopyw /* not _bcopyw, to avoid multiple mcounts */
|
||||||
cmpl $4,%eax
|
cmpl $4,%eax
|
||||||
jne _bcopyb
|
je bcopy
|
||||||
/*
|
jmp bcopyb
|
||||||
* Fall through to bcopy. ENTRY() provides harmless fill bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (ov)bcopy (src,dst,cnt)
|
* (ov)bcopy (src,dst,cnt)
|
||||||
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
|
||||||
*/
|
*/
|
||||||
ENTRY(bcopy)
|
|
||||||
ALTENTRY(ovbcopy)
|
ALTENTRY(ovbcopy)
|
||||||
|
ENTRY(bcopy)
|
||||||
|
bcopy:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 12(%esp),%esi
|
movl 12(%esp),%esi
|
||||||
@ -789,8 +831,8 @@ ALTENTRY(ovbcopy)
|
|||||||
cld
|
cld
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohl)
|
ALTENTRY(ntohl)
|
||||||
ALTENTRY(htonl)
|
ENTRY(htonl)
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
#ifdef i486
|
#ifdef i486
|
||||||
/* XXX */
|
/* XXX */
|
||||||
@ -798,7 +840,7 @@ ALTENTRY(htonl)
|
|||||||
* equivalent bytes. This can be changed back to bswap when we
|
* equivalent bytes. This can be changed back to bswap when we
|
||||||
* upgrade to a newer version of Gas */
|
* upgrade to a newer version of Gas */
|
||||||
/* bswap %eax */
|
/* bswap %eax */
|
||||||
.byte 0x0f
|
.byte 0x0f
|
||||||
.byte 0xc8
|
.byte 0xc8
|
||||||
#else
|
#else
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
@ -807,8 +849,8 @@ ALTENTRY(htonl)
|
|||||||
#endif
|
#endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(ntohs)
|
ALTENTRY(ntohs)
|
||||||
ALTENTRY(htons)
|
ENTRY(htons)
|
||||||
movzwl 4(%esp),%eax
|
movzwl 4(%esp),%eax
|
||||||
xchgb %al,%ah
|
xchgb %al,%ah
|
||||||
ret
|
ret
|
||||||
@ -861,10 +903,6 @@ show_bits:
|
|||||||
* protection violation occurs inside the functions, the trap handler
|
* protection violation occurs inside the functions, the trap handler
|
||||||
* returns to *curpcb->onfault instead of the function.
|
* returns to *curpcb->onfault instead of the function.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* XXX These routines load a segment register every time they execute.
|
|
||||||
* it would be nicer (faster) if they could depend on %gs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
||||||
@ -879,15 +917,36 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
orl %ebx, %ebx # nothing to do?
|
orl %ebx, %ebx # nothing to do?
|
||||||
jz done_copyout
|
jz done_copyout
|
||||||
|
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
/*
|
||||||
/* if WP bit in CR0 is set (n/a on 386), the hardware does the */
|
* Check explicitly for non-user addresses. If 486 write protection
|
||||||
/* write check. We just have to load the right segment selector */
|
* is being used, this check is essential because we are in kernel
|
||||||
pushl %es
|
* mode so the h/w does not provide any protection against writing
|
||||||
movl __udatasel, %eax
|
* kernel addresses.
|
||||||
movl %ax, %es
|
*
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
* Otherwise, it saves having to load and restore %es to get the
|
||||||
/* we have to check each PTE for (write) permission */
|
* usual segment-based protection (the destination segment for movs
|
||||||
|
* is always %es). The other explicit checks for user-writablility
|
||||||
|
* are not quite sufficient. They fail for the user area because
|
||||||
|
* we mapped the user area read/write to avoid having an #ifdef in
|
||||||
|
* vm_machdep.c. They fail for user PTEs and/or PTDs! (107
|
||||||
|
* addresses including 0xff800000 and 0xfc000000). I'm not sure if
|
||||||
|
* this can be fixed. Marking the PTEs supervisor mode and the
|
||||||
|
* PDE's user mode would almost work, but there may be a problem
|
||||||
|
* with the self-referential PDE.
|
||||||
|
*/
|
||||||
|
movl %edi, %eax
|
||||||
|
addl %ebx, %eax
|
||||||
|
jc copyout_fault
|
||||||
|
#define VM_END_USER_ADDRESS 0xFDBFE000 /* XXX */
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %eax
|
||||||
|
ja copyout_fault
|
||||||
|
|
||||||
|
#ifndef USE_486_WRITE_PROTECT
|
||||||
|
/*
|
||||||
|
* We have to check each PTE for user write permission.
|
||||||
|
* The checking may cause a page fault, so it is important to set
|
||||||
|
* up everything for return via copyout_fault before here.
|
||||||
|
*/
|
||||||
/* compute number of pages */
|
/* compute number of pages */
|
||||||
movl %edi, %ecx
|
movl %edi, %ecx
|
||||||
andl $0x0fff, %ecx
|
andl $0x0fff, %ecx
|
||||||
@ -906,7 +965,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
|
||||||
cmpb $0x07, %al
|
cmpb $0x07, %al
|
||||||
je 2f
|
je 2f
|
||||||
|
|
||||||
/* simulate a trap */
|
/* simulate a trap */
|
||||||
pushl %edx
|
pushl %edx
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
@ -924,8 +983,7 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
addl $4, %edx
|
addl $4, %edx
|
||||||
decl %ecx
|
decl %ecx
|
||||||
jnz 1b /* check next page */
|
jnz 1b /* check next page */
|
||||||
|
#endif /* ndef USE_486_WRITE_PROTECT */
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
|
||||||
|
|
||||||
/* now copy it over */
|
/* now copy it over */
|
||||||
/* bcopy (%esi, %edi, %ebx) */
|
/* bcopy (%esi, %edi, %ebx) */
|
||||||
@ -938,9 +996,6 @@ ENTRY(copyout) # copyout (from_kernel, to_user, len)
|
|||||||
andb $3, %cl
|
andb $3, %cl
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
|
|
||||||
done_copyout:
|
done_copyout:
|
||||||
popl %ebx
|
popl %ebx
|
||||||
@ -951,10 +1006,8 @@ done_copyout:
|
|||||||
movl %eax,PCB_ONFAULT(%edx)
|
movl %eax,PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyout_fault:
|
copyout_fault:
|
||||||
#ifdef USE_486_WRITE_PROTECT
|
|
||||||
popl %es
|
|
||||||
#endif
|
|
||||||
popl %ebx
|
popl %ebx
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
@ -972,22 +1025,19 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl 12(%esp),%esi # caddr_t from
|
movl 12(%esp),%esi # caddr_t from
|
||||||
movl 16(%esp),%edi # caddr_t to
|
movl 16(%esp),%edi # caddr_t to
|
||||||
movl 20(%esp),%ecx # size_t len
|
movl 20(%esp),%ecx # size_t len
|
||||||
movl %ecx,%edx
|
|
||||||
pushl %ds
|
|
||||||
movl __udatasel,%ax # access 'from' via user data segment
|
|
||||||
movl %ax,%ds
|
|
||||||
|
|
||||||
movb %cl,%al
|
movb %cl,%al
|
||||||
shrl $2,%ecx # copy longword-wise
|
shrl $2,%ecx # copy longword-wise
|
||||||
cld
|
cld
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsl
|
movsl
|
||||||
movb %al,%cl
|
movb %al,%cl
|
||||||
andb $3,%cl # copy remaining bytes
|
andb $3,%cl # copy remaining bytes
|
||||||
|
gs
|
||||||
rep
|
rep
|
||||||
movsb
|
movsb
|
||||||
|
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
@ -995,8 +1045,8 @@ ENTRY(copyin) # copyin (from_user, to_kernel, len)
|
|||||||
movl %eax, PCB_ONFAULT(%edx)
|
movl %eax, PCB_ONFAULT(%edx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
copyin_fault:
|
copyin_fault:
|
||||||
popl %ds
|
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
movl _curpcb, %edx
|
movl _curpcb, %edx
|
||||||
@ -1007,10 +1057,8 @@ copyin_fault:
|
|||||||
/*
|
/*
|
||||||
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
||||||
*/
|
*/
|
||||||
ENTRY(fuword)
|
|
||||||
ALTENTRY(fuiword)
|
ALTENTRY(fuiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(fuword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1018,10 +1066,8 @@ ALTENTRY(fuiword)
|
|||||||
movl (%edx),%eax
|
movl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fusword)
|
ENTRY(fusword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1029,11 +1075,9 @@ ENTRY(fusword)
|
|||||||
movzwl (%edx),%eax
|
movzwl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(fubyte)
|
|
||||||
ALTENTRY(fuibyte)
|
ALTENTRY(fuibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(fubyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
@ -1041,7 +1085,8 @@ ALTENTRY(fuibyte)
|
|||||||
movzbl (%edx),%eax
|
movzbl (%edx),%eax
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
movl $0,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
fusufault:
|
fusufault:
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
@ -1056,42 +1101,39 @@ fusufault:
|
|||||||
/*
|
/*
|
||||||
* we only have to set the right segment selector.
|
* we only have to set the right segment selector.
|
||||||
*/
|
*/
|
||||||
ENTRY(suword)
|
|
||||||
ALTENTRY(suiword)
|
ALTENTRY(suiword)
|
||||||
movl __udatasel,%eax
|
ENTRY(suword)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movl 8(%esp),%eax
|
movl 8(%esp),%eax
|
||||||
gs
|
gs
|
||||||
movl %eax,(%edx)
|
movl %eax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(susword)
|
ENTRY(susword)
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movw 8(%esp),%ax
|
movw 8(%esp),%ax
|
||||||
gs
|
gs
|
||||||
movw %ax,(%edx)
|
movw %ax,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ENTRY(subyte)
|
|
||||||
ALTENTRY(suibyte)
|
ALTENTRY(suibyte)
|
||||||
movl __udatasel,%eax
|
ENTRY(subyte)
|
||||||
movl %ax,%gs
|
|
||||||
movl _curpcb,%ecx
|
movl _curpcb,%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
movb 8(%esp),%al
|
movb 8(%esp),%al
|
||||||
gs
|
gs
|
||||||
movb %al,(%edx)
|
movb %al,(%edx)
|
||||||
movl $0,PCB_ONFAULT(%ecx)
|
xorl %eax,%eax
|
||||||
|
movl %eax,PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -1102,8 +1144,8 @@ ALTENTRY(suibyte)
|
|||||||
*/
|
*/
|
||||||
# XXX - page boundary crossing is not handled yet
|
# XXX - page boundary crossing is not handled yet
|
||||||
|
|
||||||
|
ALTENTRY(suibyte)
|
||||||
ENTRY(subyte)
|
ENTRY(subyte)
|
||||||
ENTRY(suibyte)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1123,6 +1165,7 @@ ENTRY(suibyte)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movb %al, (%edx)
|
movb %al, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1149,14 +1192,15 @@ ENTRY(susword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movw %ax, (%edx)
|
movw %ax, (%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl %eax, PCB_ONFAULT(%ecx)
|
movl %eax, PCB_ONFAULT(%ecx)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ALTENTRY(suiword)
|
||||||
ENTRY(suword)
|
ENTRY(suword)
|
||||||
ENTRY(suiword)
|
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
movl $fusufault, PCB_ONFAULT(%ecx)
|
movl $fusufault, PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
@ -1176,6 +1220,7 @@ ENTRY(suiword)
|
|||||||
1:
|
1:
|
||||||
movl 4(%esp), %edx
|
movl 4(%esp), %edx
|
||||||
movl 8(%esp), %eax
|
movl 8(%esp), %eax
|
||||||
|
gs
|
||||||
movl %eax, 0(%edx)
|
movl %eax, 0(%edx)
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl _curpcb, %ecx
|
movl _curpcb, %ecx
|
||||||
@ -1183,6 +1228,7 @@ ENTRY(suiword)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* copyoutstr(from, to, maxlen, int *lencopied)
|
* copyoutstr(from, to, maxlen, int *lencopied)
|
||||||
* copy a string from from to to, stop when a 0 character is reached.
|
* copy a string from from to to, stop when a 0 character is reached.
|
||||||
@ -1201,13 +1247,19 @@ ENTRY(copyoutstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
decl %edx
|
decl %edx
|
||||||
jz 4f
|
jz 4f
|
||||||
|
/*
|
||||||
|
* gs override doesn't work for stosb. Use the same explicit check
|
||||||
|
* as in copyout(). It's much slower now because it is per-char.
|
||||||
|
* XXX - however, it would be faster to rewrite this function to use
|
||||||
|
* strlen() and copyout().
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
lodsb
|
lodsb
|
||||||
gs
|
gs
|
||||||
stosb
|
stosb
|
||||||
@ -1222,7 +1274,7 @@ ENTRY(copyoutstr)
|
|||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#else /* USE_486_WRITE_PROTECT */
|
#else /* ndef USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
ENTRY(copyoutstr)
|
ENTRY(copyoutstr)
|
||||||
pushl %esi
|
pushl %esi
|
||||||
@ -1234,6 +1286,13 @@ ENTRY(copyoutstr)
|
|||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
1:
|
1:
|
||||||
|
/*
|
||||||
|
* It suffices to check that the first byte is in user space, because
|
||||||
|
* we look at a page at a time and the end address is on a page
|
||||||
|
* boundary.
|
||||||
|
*/
|
||||||
|
cmpl $VM_END_USER_ADDRESS, %edi
|
||||||
|
jae cpystrflt
|
||||||
movl %edi, %eax
|
movl %edi, %eax
|
||||||
shrl $IDXSHIFT, %eax
|
shrl $IDXSHIFT, %eax
|
||||||
andb $0xfc, %al
|
andb $0xfc, %al
|
||||||
@ -1280,6 +1339,7 @@ ENTRY(copyoutstr)
|
|||||||
/* edx is zero -- return ENAMETOOLONG */
|
/* edx is zero -- return ENAMETOOLONG */
|
||||||
movl $ENAMETOOLONG, %eax
|
movl $ENAMETOOLONG, %eax
|
||||||
jmp 6f
|
jmp 6f
|
||||||
|
|
||||||
#endif /* USE_486_WRITE_PROTECT */
|
#endif /* USE_486_WRITE_PROTECT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1298,8 +1358,6 @@ ENTRY(copyinstr)
|
|||||||
movl 12(%esp), %esi # %esi = from
|
movl 12(%esp), %esi # %esi = from
|
||||||
movl 16(%esp), %edi # %edi = to
|
movl 16(%esp), %edi # %edi = to
|
||||||
movl 20(%esp), %edx # %edx = maxlen
|
movl 20(%esp), %edx # %edx = maxlen
|
||||||
movl __udatasel,%eax
|
|
||||||
movl %ax,%gs
|
|
||||||
incl %edx
|
incl %edx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
@ -1447,13 +1505,12 @@ ENTRY(ssdtosd) # ssdtosd(*ssdp,*sdp)
|
|||||||
|
|
||||||
ENTRY(tlbflush) # tlbflush()
|
ENTRY(tlbflush) # tlbflush()
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
ENTRY(lcr0) # lcr0(cr0)
|
ENTRY(load_cr0) # load_cr0(cr0)
|
||||||
ALTENTRY(load_cr0)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
movl %eax,%cr0
|
movl %eax,%cr0
|
||||||
ret
|
ret
|
||||||
@ -1470,18 +1527,13 @@ ENTRY(rcr2) # rcr2()
|
|||||||
|
|
||||||
|
|
||||||
ENTRY(rcr3) # rcr3()
|
ENTRY(rcr3) # rcr3()
|
||||||
ALTENTRY(_cr3)
|
|
||||||
movl %cr3,%eax
|
movl %cr3,%eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
/*
|
ENTRY(load_cr3) # void load_cr3(caddr_t cr3)
|
||||||
* void lcr3(caddr_t cr3)
|
|
||||||
*/
|
|
||||||
ENTRY(lcr3)
|
|
||||||
ALTENTRY(load_cr3)
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
orl $ I386_CR3PAT,%eax
|
orl $ I386_CR3PAT,%eax
|
||||||
movl %eax,%cr3
|
movl %eax,%cr3
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1600,17 +1652,19 @@ sw0: .asciz "swtch"
|
|||||||
* When no processes are on the runq, Swtch branches to idle
|
* When no processes are on the runq, Swtch branches to idle
|
||||||
* to wait for something to come ready.
|
* to wait for something to come ready.
|
||||||
*/
|
*/
|
||||||
LENTRY(Idle)
|
ALIGN_TEXT
|
||||||
|
Idle:
|
||||||
sti
|
sti
|
||||||
SHOW_STI
|
SHOW_STI
|
||||||
|
|
||||||
|
ALIGN_TEXT
|
||||||
idle_loop:
|
idle_loop:
|
||||||
call _spl0
|
call _spl0
|
||||||
cmpl $0,_whichqs
|
cmpl $0,_whichqs
|
||||||
jne sw1
|
jne sw1
|
||||||
hlt # wait for interrupt
|
hlt # wait for interrupt
|
||||||
jmp idle_loop
|
jmp idle_loop
|
||||||
|
|
||||||
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
|
||||||
badsw:
|
badsw:
|
||||||
pushl $sw0
|
pushl $sw0
|
||||||
call _panic
|
call _panic
|
||||||
@ -1619,6 +1673,7 @@ badsw:
|
|||||||
/*
|
/*
|
||||||
* Swtch()
|
* Swtch()
|
||||||
*/
|
*/
|
||||||
|
SUPERALIGN_TEXT /* so profiling doesn't lump Idle with swtch().. */
|
||||||
ENTRY(swtch)
|
ENTRY(swtch)
|
||||||
|
|
||||||
incl _cnt+V_SWTCH
|
incl _cnt+V_SWTCH
|
||||||
@ -1780,7 +1835,7 @@ ENTRY(savectx)
|
|||||||
movl 4(%esp), %ecx
|
movl 4(%esp), %ecx
|
||||||
movw _cpl, %ax
|
movw _cpl, %ax
|
||||||
movw %ax, PCB_IML(%ecx)
|
movw %ax, PCB_IML(%ecx)
|
||||||
movl (%esp), %eax
|
movl (%esp), %eax
|
||||||
movl %eax, PCB_EIP(%ecx)
|
movl %eax, PCB_EIP(%ecx)
|
||||||
movl %ebx, PCB_EBX(%ecx)
|
movl %ebx, PCB_EBX(%ecx)
|
||||||
movl %esp, PCB_ESP(%ecx)
|
movl %esp, PCB_ESP(%ecx)
|
||||||
@ -1885,7 +1940,7 @@ L1:
|
|||||||
proffault:
|
proffault:
|
||||||
/* if we get a fault, then kill profiling all together */
|
/* if we get a fault, then kill profiling all together */
|
||||||
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
movl $0,PCB_ONFAULT(%edx) /* squish the fault handler */
|
||||||
movl 12(%ebp),%ecx
|
movl 12(%ebp),%ecx
|
||||||
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
movl $0,PR_SCALE(%ecx) /* up->pr_scale = 0 */
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
@ -1903,7 +1958,7 @@ ENTRY(astoff)
|
|||||||
*
|
*
|
||||||
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
* XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
|
||||||
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
* control. The sti's give the standard losing behaviour for ddb and kgdb.
|
||||||
*/
|
*/
|
||||||
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
#define IDTVEC(name) ALIGN_TEXT; .globl _X/**/name; _X/**/name:
|
||||||
#define TRAP(a) pushl $(a) ; jmp alltraps
|
#define TRAP(a) pushl $(a) ; jmp alltraps
|
||||||
#ifdef KGDB
|
#ifdef KGDB
|
||||||
@ -2048,14 +2103,14 @@ bpttraps:
|
|||||||
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
|
||||||
# non-kernel mode?
|
# non-kernel mode?
|
||||||
jne calltrap # yes
|
jne calltrap # yes
|
||||||
call _kgdb_trap_glue
|
call _kgdb_trap_glue
|
||||||
jmp calltrap
|
jmp calltrap
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call gate entry for syscall
|
* Call gate entry for syscall
|
||||||
*/
|
*/
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
IDTVEC(syscall)
|
IDTVEC(syscall)
|
||||||
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
pushfl # only for stupid carry bit and more stupid wait3 cc kludge
|
||||||
# XXX - also for direction flag (bzero, etc. clear it)
|
# XXX - also for direction flag (bzero, etc. clear it)
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
* 20 Apr 93 Bruce Evans New npx-0.5 code
|
* 20 Apr 93 Bruce Evans New npx-0.5 code
|
||||||
* 25 Apr 93 Bruce Evans New intr-0.1 code
|
* 25 Apr 93 Bruce Evans New intr-0.1 code
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/i386/i386/machdep.c,v 1.3 1993/07/16 20:50:42 davidg Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/machdep.c,v 1.4 1993/07/16 23:55:07 davidg Exp $";
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -849,16 +849,41 @@ init386(first)
|
|||||||
* Initialize the console before we print anything out.
|
* Initialize the console before we print anything out.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cninit (KERNBASE+0xa0000);
|
cninit ();
|
||||||
|
|
||||||
/* make gdt memory segments */
|
/* make gdt memory segments */
|
||||||
gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
|
gdt_segs[GCODE_SEL].ssd_limit = i386_btop(i386_round_page(&etext)) - 1;
|
||||||
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, &gdt[x][0]);
|
/*
|
||||||
|
* XXX - VM_MAX_KERNEL_ADDRESS is correctly a max, but bogusly the
|
||||||
|
* address of the last page, not the last byte. Then above the end
|
||||||
|
* :-) there is another 4M of page tables or something.
|
||||||
|
*/
|
||||||
|
#define VM_END_KERNEL_ADDRESS (VM_MAX_KERNEL_ADDRESS + NBPG + NBPDR)
|
||||||
|
gdt_segs[GDATA_SEL].ssd_limit = i386_btop(VM_END_KERNEL_ADDRESS) - 1;
|
||||||
|
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
|
||||||
/* make ldt memory segments */
|
/* make ldt memory segments */
|
||||||
ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
|
/*
|
||||||
ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
|
* The data segment limit must not cover the user area because we
|
||||||
|
* don't want the user area to be writable in copyout() etc. (page
|
||||||
|
* level protection is lost in kernel mode on 386's). Also, we
|
||||||
|
* don't want the user area to be writable directly (page level
|
||||||
|
* protection of the user area is not available on 486's with
|
||||||
|
* CR0_WP set, because there is no user-read/kernel-write mode).
|
||||||
|
*
|
||||||
|
* XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it
|
||||||
|
* should be spelled ...MAX_USER...
|
||||||
|
*/
|
||||||
|
#define VM_END_USER_RW_ADDRESS VM_MAXUSER_ADDRESS
|
||||||
|
/*
|
||||||
|
* The code segment limit has to cover the user area until we move
|
||||||
|
* the signal trampoline out of the user area. This is safe because
|
||||||
|
* the code segment cannot be written to directly.
|
||||||
|
*/
|
||||||
|
#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
|
||||||
|
ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
|
||||||
|
ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
|
||||||
/* Note. eventually want private ldts per process */
|
/* Note. eventually want private ldts per process */
|
||||||
for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, &ldt[x][0]);
|
for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
|
||||||
|
|
||||||
/* exceptions */
|
/* exceptions */
|
||||||
setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
|
setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
|
||||||
@ -951,7 +976,8 @@ init386(first)
|
|||||||
Maxmem = 640/4;
|
Maxmem = 640/4;
|
||||||
else {
|
else {
|
||||||
Maxmem = pagesinext + 0x100000/NBPG;
|
Maxmem = pagesinext + 0x100000/NBPG;
|
||||||
first = 0x100000; /* skip hole */
|
if (first < 0x100000)
|
||||||
|
first = 0x100000; /* skip hole */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This used to explode, since Maxmem used to be 0 for bas CMOS*/
|
/* This used to explode, since Maxmem used to be 0 for bas CMOS*/
|
||||||
@ -1077,6 +1103,7 @@ _remque(element)
|
|||||||
element->ph_rlink = (struct proc *)0;
|
element->ph_rlink = (struct proc *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SLOW_OLD_COPYSTRS
|
||||||
vmunaccess() {}
|
vmunaccess() {}
|
||||||
|
|
||||||
#if 0 /* assembler versions now in locore.s */
|
#if 0 /* assembler versions now in locore.s */
|
||||||
@ -1124,6 +1151,8 @@ copyoutstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
|||||||
return(ENAMETOOLONG);
|
return(ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* SLOW_OLD_COPYSTRS */
|
||||||
|
|
||||||
copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
|
||||||
void *fromaddr, *toaddr; {
|
void *fromaddr, *toaddr; {
|
||||||
u_int tally;
|
u_int tally;
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
*
|
*
|
||||||
* 28 Nov 1991 Poul-Henning Kamp Speedup processing.
|
* 28 Nov 1991 Poul-Henning Kamp Speedup processing.
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /usr/src/sys.386bsd/i386/i386/RCS/pmap.c,v 1.3 92/01/21 14:26:44 william Exp Locker: root $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/pmap.c,v 1.1.1.1 1993/06/12 14:58:06 rgrimes Exp $";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Derived from hp300 version by Mike Hibler, this version by William
|
* Derived from hp300 version by Mike Hibler, this version by William
|
||||||
@ -461,7 +461,7 @@ pmap_pinit(pmap)
|
|||||||
|
|
||||||
/* install self-referential address mapping entry */
|
/* install self-referential address mapping entry */
|
||||||
*(int *)(pmap->pm_pdir+PTDPTDI) =
|
*(int *)(pmap->pm_pdir+PTDPTDI) =
|
||||||
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_URKW;
|
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_KW;
|
||||||
|
|
||||||
pmap->pm_count = 1;
|
pmap->pm_count = 1;
|
||||||
simple_lock_init(&pmap->pm_lock);
|
simple_lock_init(&pmap->pm_lock);
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
* 08 Apr 93 Bruce Evans Several VM system fixes
|
* 08 Apr 93 Bruce Evans Several VM system fixes
|
||||||
* Paul Kranenburg Add counter for vmstat
|
* Paul Kranenburg Add counter for vmstat
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2 92/01/21 14:22:13 william Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/trap.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 386 Trap and System call handleing
|
* 386 Trap and System call handleing
|
||||||
@ -70,6 +70,21 @@ static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2
|
|||||||
|
|
||||||
#include "machine/trap.h"
|
#include "machine/trap.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
|
||||||
|
* we omit the size from the mov instruction to avoid nonfatal bugs in gas.
|
||||||
|
*/
|
||||||
|
#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
|
||||||
|
#define write_gs(gs) __asm("mov %0,%%gs" : : "r" ((u_short) gs))
|
||||||
|
|
||||||
|
#else /* not __GNUC__ */
|
||||||
|
|
||||||
|
u_short read_gs __P((void));
|
||||||
|
void write_gs __P((/* promoted u_short */ int gs));
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
struct sysent sysent[];
|
struct sysent sysent[];
|
||||||
int nsysent;
|
int nsysent;
|
||||||
@ -112,9 +127,25 @@ trap(frame)
|
|||||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||||
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
||||||
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||||
if (curpcb->pcb_onfault && frame.tf_trapno != 0xc) {
|
if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) {
|
||||||
|
extern int _udatasel;
|
||||||
|
|
||||||
|
if (read_gs() != (u_short) _udatasel)
|
||||||
|
/*
|
||||||
|
* Some user has corrupted %gs but we depend on it in
|
||||||
|
* copyout() etc. Fix it up and retry.
|
||||||
|
*
|
||||||
|
* (We don't preserve %fs or %gs, so users can change
|
||||||
|
* them to either _ucodesel, _udatasel or a not-present
|
||||||
|
* selector, possibly ORed with 0 to 3, making them
|
||||||
|
* volatile for other users. Not preserving them saves
|
||||||
|
* time and doesn't lose functionality or open security
|
||||||
|
* holes.)
|
||||||
|
*/
|
||||||
|
write_gs(_udatasel);
|
||||||
|
else
|
||||||
copyfault:
|
copyfault:
|
||||||
frame.tf_eip = (int)curpcb->pcb_onfault;
|
frame.tf_eip = (int)curpcb->pcb_onfault;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,18 +427,49 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensate for 386 brain damage (missing URKR)
|
* Compensate for 386 brain damage (missing URKR).
|
||||||
|
* This is a little simpler than the pagefault handler in trap() because
|
||||||
|
* it the page tables have already been faulted in and high addresses
|
||||||
|
* are thrown out early for other reasons.
|
||||||
*/
|
*/
|
||||||
int trapwrite(unsigned addr) {
|
int trapwrite(addr)
|
||||||
int rv;
|
unsigned addr;
|
||||||
|
{
|
||||||
|
unsigned nss;
|
||||||
|
struct proc *p;
|
||||||
vm_offset_t va;
|
vm_offset_t va;
|
||||||
|
struct vmspace *vm;
|
||||||
|
|
||||||
va = trunc_page((vm_offset_t)addr);
|
va = trunc_page((vm_offset_t)addr);
|
||||||
if (va > VM_MAXUSER_ADDRESS) return(1);
|
/*
|
||||||
rv = vm_fault(&curproc->p_vmspace->vm_map, va,
|
* XXX - MAX is END. Changed > to >= for temp. fix.
|
||||||
VM_PROT_READ | VM_PROT_WRITE, FALSE);
|
*/
|
||||||
if (rv == KERN_SUCCESS) return(0);
|
if (va >= VM_MAXUSER_ADDRESS)
|
||||||
else return(1);
|
return (1);
|
||||||
|
/*
|
||||||
|
* XXX: rude stack hack adapted from trap().
|
||||||
|
*/
|
||||||
|
nss = 0;
|
||||||
|
p = curproc;
|
||||||
|
vm = p->p_vmspace;
|
||||||
|
if ((caddr_t)va >= vm->vm_maxsaddr && dostacklimits) {
|
||||||
|
nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ
|
||||||
|
- (unsigned)va));
|
||||||
|
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE)
|
||||||
|
!= KERN_SUCCESS)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: continuation of rude stack hack
|
||||||
|
*/
|
||||||
|
if (nss > vm->vm_ssize)
|
||||||
|
vm->vm_ssize = nss;
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
/*
|
/*
|
||||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/i386/i386/vm_machdep.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/vm_machdep.c,v 1.2 1993/07/18 20:56:17 paul Exp $";
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include "systm.h"
|
#include "systm.h"
|
||||||
@ -105,8 +105,15 @@ cpu_fork(p1, p2)
|
|||||||
vm_map_pageable(&p2->p_vmspace->vm_map, addr, addr+NBPG, FALSE);
|
vm_map_pageable(&p2->p_vmspace->vm_map, addr, addr+NBPG, FALSE);
|
||||||
for (i=0; i < UPAGES; i++)
|
for (i=0; i < UPAGES; i++)
|
||||||
pmap_enter(&p2->p_vmspace->vm_pmap, kstack+i*NBPG,
|
pmap_enter(&p2->p_vmspace->vm_pmap, kstack+i*NBPG,
|
||||||
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG), VM_PROT_READ, 1);
|
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG),
|
||||||
|
/*
|
||||||
|
* The user area has to be mapped writable because
|
||||||
|
* it contains the kernel stack (when CR0_WP is on
|
||||||
|
* on a 486 there is no user-read/kernel-write
|
||||||
|
* mode). It is protected from user mode access
|
||||||
|
* by the segment limits.
|
||||||
|
*/
|
||||||
|
VM_PROT_READ|VM_PROT_WRITE, TRUE);
|
||||||
pmap_activate(&p2->p_vmspace->vm_pmap, &up->u_pcb);
|
pmap_activate(&p2->p_vmspace->vm_pmap, &up->u_pcb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -53,10 +53,12 @@
|
|||||||
* these are defined to get generic functions
|
* these are defined to get generic functions
|
||||||
* rather than inline or machine-dependent implementations
|
* rather than inline or machine-dependent implementations
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
#define NEED_MINMAX /* need {,i,l,ul}{min,max} functions */
|
#define NEED_MINMAX /* need {,i,l,ul}{min,max} functions */
|
||||||
#define NEED_FFS /* need ffs function */
|
#define NEED_FFS /* need ffs function */
|
||||||
#define NEED_BCMP /* need bcmp function */
|
#define NEED_BCMP /* need bcmp function */
|
||||||
#define NEED_STRLEN /* need strlen function */
|
#define NEED_STRLEN /* need strlen function */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define cpu_exec(p) /* nothing */
|
#define cpu_exec(p) /* nothing */
|
||||||
|
|
||||||
|
@ -58,6 +58,116 @@ outb(u_int port, u_char data)
|
|||||||
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
|
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
imin(a, b)
|
||||||
|
int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
imax(a, b)
|
||||||
|
int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned int
|
||||||
|
min(a, b)
|
||||||
|
unsigned int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned int
|
||||||
|
max(a, b)
|
||||||
|
unsigned int a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
long
|
||||||
|
lmin(a, b)
|
||||||
|
long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
long
|
||||||
|
lmax(a, b)
|
||||||
|
long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned long
|
||||||
|
ulmin(a, b)
|
||||||
|
unsigned long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
unsigned long
|
||||||
|
ulmax(a, b)
|
||||||
|
unsigned long a, b;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
ffs(mask)
|
||||||
|
register long mask;
|
||||||
|
{
|
||||||
|
register int bit;
|
||||||
|
|
||||||
|
if (!mask)
|
||||||
|
return(0);
|
||||||
|
for (bit = 1;; ++bit) {
|
||||||
|
if (mask&0x01)
|
||||||
|
return(bit);
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
bcmp(v1, v2, len)
|
||||||
|
void *v1, *v2;
|
||||||
|
register unsigned len;
|
||||||
|
{
|
||||||
|
register u_char *s1 = v1, *s2 = v2;
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
if (*s1++ != *s2++)
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__
|
||||||
|
size_t
|
||||||
|
strlen(s1)
|
||||||
|
register __const__ char *s1;
|
||||||
|
{
|
||||||
|
register size_t len;
|
||||||
|
|
||||||
|
for (len = 0; *s1++ != '\0'; len++)
|
||||||
|
;
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
#else /* not __GNUC__ */
|
#else /* not __GNUC__ */
|
||||||
|
|
||||||
int bdb __P((void));
|
int bdb __P((void));
|
||||||
@ -80,3 +190,4 @@ really_void setidt __P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
|
|||||||
|
|
||||||
#undef really_u_int
|
#undef really_u_int
|
||||||
#undef really_void
|
#undef really_void
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
* Modification history
|
* Modification history
|
||||||
*
|
*
|
||||||
* $Log: if_ed.c,v $
|
* $Log: if_ed.c,v $
|
||||||
|
* Revision 1.18 93/07/27 03:41:36 davidg
|
||||||
|
* removed unnecessary variable assignment in ed_reset()
|
||||||
|
*
|
||||||
* Revision 1.17 93/07/26 18:40:57 davidg
|
* Revision 1.17 93/07/26 18:40:57 davidg
|
||||||
* Added include of systm.h to pick up inlined min/max/bcmp if you have
|
* Added include of systm.h to pick up inlined min/max/bcmp if you have
|
||||||
* them in cpufunc.h. Modified wait loop in reset to look a little better.
|
* them in cpufunc.h. Modified wait loop in reset to look a little better.
|
||||||
@ -798,7 +801,7 @@ ed_reset(unit)
|
|||||||
ed_stop(unit);
|
ed_stop(unit);
|
||||||
ed_init(unit);
|
ed_init(unit);
|
||||||
|
|
||||||
s = splx(s);
|
(void) splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "bpfilter.h"
|
#include "bpfilter.h"
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "systm.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "ioctl.h"
|
#include "ioctl.h"
|
||||||
#include "mbuf.h"
|
#include "mbuf.h"
|
||||||
@ -171,7 +172,7 @@ int is_reset(int unit)
|
|||||||
s = splnet();
|
s = splnet();
|
||||||
printf("is%d: reset\n", unit);
|
printf("is%d: reset\n", unit);
|
||||||
is_init(unit);
|
is_init(unit);
|
||||||
s = splx();
|
(void) splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#if NSPEAKER > 0
|
#if NSPEAKER > 0
|
||||||
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "systm.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
* 08 Apr 93 Bruce Evans Several VM system fixes
|
* 08 Apr 93 Bruce Evans Several VM system fixes
|
||||||
* Paul Kranenburg Add counter for vmstat
|
* Paul Kranenburg Add counter for vmstat
|
||||||
*/
|
*/
|
||||||
static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2 92/01/21 14:22:13 william Exp $";
|
static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/i386/trap.c,v 1.1.1.1 1993/06/12 14:58:05 rgrimes Exp $";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 386 Trap and System call handleing
|
* 386 Trap and System call handleing
|
||||||
@ -70,6 +70,21 @@ static char rcsid[] = "$Header: /usr/bill/working/sys/i386/i386/RCS/trap.c,v 1.2
|
|||||||
|
|
||||||
#include "machine/trap.h"
|
#include "machine/trap.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "r" contraint could be "rm" except for fatal bugs in gas. As usual,
|
||||||
|
* we omit the size from the mov instruction to avoid nonfatal bugs in gas.
|
||||||
|
*/
|
||||||
|
#define read_gs() ({ u_short gs; __asm("mov %%gs,%0" : "=r" (gs)); gs; })
|
||||||
|
#define write_gs(gs) __asm("mov %0,%%gs" : : "r" ((u_short) gs))
|
||||||
|
|
||||||
|
#else /* not __GNUC__ */
|
||||||
|
|
||||||
|
u_short read_gs __P((void));
|
||||||
|
void write_gs __P((/* promoted u_short */ int gs));
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
struct sysent sysent[];
|
struct sysent sysent[];
|
||||||
int nsysent;
|
int nsysent;
|
||||||
@ -112,9 +127,25 @@ trap(frame)
|
|||||||
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
frame.tf_trapno, frame.tf_err, frame.tf_eip,
|
||||||
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
frame.tf_cs, rcr2(), frame.tf_esp);*/
|
||||||
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
||||||
if (curpcb->pcb_onfault && frame.tf_trapno != 0xc) {
|
if (curpcb->pcb_onfault && frame.tf_trapno != T_PAGEFLT) {
|
||||||
|
extern int _udatasel;
|
||||||
|
|
||||||
|
if (read_gs() != (u_short) _udatasel)
|
||||||
|
/*
|
||||||
|
* Some user has corrupted %gs but we depend on it in
|
||||||
|
* copyout() etc. Fix it up and retry.
|
||||||
|
*
|
||||||
|
* (We don't preserve %fs or %gs, so users can change
|
||||||
|
* them to either _ucodesel, _udatasel or a not-present
|
||||||
|
* selector, possibly ORed with 0 to 3, making them
|
||||||
|
* volatile for other users. Not preserving them saves
|
||||||
|
* time and doesn't lose functionality or open security
|
||||||
|
* holes.)
|
||||||
|
*/
|
||||||
|
write_gs(_udatasel);
|
||||||
|
else
|
||||||
copyfault:
|
copyfault:
|
||||||
frame.tf_eip = (int)curpcb->pcb_onfault;
|
frame.tf_eip = (int)curpcb->pcb_onfault;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,18 +427,49 @@ if(curpcb == 0 || curproc == 0) goto we_re_toast;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensate for 386 brain damage (missing URKR)
|
* Compensate for 386 brain damage (missing URKR).
|
||||||
|
* This is a little simpler than the pagefault handler in trap() because
|
||||||
|
* it the page tables have already been faulted in and high addresses
|
||||||
|
* are thrown out early for other reasons.
|
||||||
*/
|
*/
|
||||||
int trapwrite(unsigned addr) {
|
int trapwrite(addr)
|
||||||
int rv;
|
unsigned addr;
|
||||||
|
{
|
||||||
|
unsigned nss;
|
||||||
|
struct proc *p;
|
||||||
vm_offset_t va;
|
vm_offset_t va;
|
||||||
|
struct vmspace *vm;
|
||||||
|
|
||||||
va = trunc_page((vm_offset_t)addr);
|
va = trunc_page((vm_offset_t)addr);
|
||||||
if (va > VM_MAXUSER_ADDRESS) return(1);
|
/*
|
||||||
rv = vm_fault(&curproc->p_vmspace->vm_map, va,
|
* XXX - MAX is END. Changed > to >= for temp. fix.
|
||||||
VM_PROT_READ | VM_PROT_WRITE, FALSE);
|
*/
|
||||||
if (rv == KERN_SUCCESS) return(0);
|
if (va >= VM_MAXUSER_ADDRESS)
|
||||||
else return(1);
|
return (1);
|
||||||
|
/*
|
||||||
|
* XXX: rude stack hack adapted from trap().
|
||||||
|
*/
|
||||||
|
nss = 0;
|
||||||
|
p = curproc;
|
||||||
|
vm = p->p_vmspace;
|
||||||
|
if ((caddr_t)va >= vm->vm_maxsaddr && dostacklimits) {
|
||||||
|
nss = clrnd(btoc((unsigned)vm->vm_maxsaddr + MAXSSIZ
|
||||||
|
- (unsigned)va));
|
||||||
|
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm_fault(&vm->vm_map, va, VM_PROT_READ | VM_PROT_WRITE, FALSE)
|
||||||
|
!= KERN_SUCCESS)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: continuation of rude stack hack
|
||||||
|
*/
|
||||||
|
if (nss > vm->vm_ssize)
|
||||||
|
vm->vm_ssize = nss;
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user