#include <machine/asm.h>
#include "assym.h"
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
#include "opt_compat_netbsd.h"
#include "opt_compat_ultrix.h"
#ifdef COMPAT_ULTRIX
#include <compat/ultrix/ultrix_syscall.h>
#endif
#define JSBENTRY(x) .globl x ; .align 2 ; x :
#define SCBENTRY(name) \
.text ; \
.align 2 ; \
.globl __CONCAT(X,name) ; \
__CONCAT(X,name):
.text
#ifdef KERNEL_LOADABLE_BY_MOP
cps:
2: movb (%r0)+,(%r1)+
cmpl %r0,%r7
bneq 2b
3: clrb (%r1)+
incl %r0
cmpl %r0,%r6
bneq 3b
clrl -(%sp)
movl %sp,%ap
movl $_cca,%r7
movl %r8,(%r7)
movpsl -(%sp)
pushl %r2
rei
cpe:
1: movab cps,%r0
movab cpe,%r1
movl $0x300000,%sp
movl %sp,%r3
4: movb (%r0)+,(%r3)+
cmpl %r0,%r1
bneq 4b
movl %r7,%r8
movab _edata,%r7
movab _end,%r6
movl $0x80000000,%r1
movl $0x80000200,%r0
subl3 $0x200,%r6,%r9
movab 2f,%r2
subl2 $0x200,%r2
movpsl -(%sp)
pushab 4(%sp)
rei
JSBENTRY(start)
brb 1b # Netbooted starts here
#else
ASENTRY(start, 0)
#endif
2: bisl3 $0x80000000,%r9,_C_LABEL(esym) # End of loaded code
pushl $0x1f0000 # Push a nice PSL
pushl $to # Address to jump to
rei # change to kernel stack
to: movw $0xfff,_C_LABEL(panic) # Save all regs in panic
cmpb (%ap),$3 # symbols info present?
blssu 3f # nope, skip
bisl3 $0x80000000,8(%ap),_C_LABEL(symtab_start)
movl 12(%ap),_C_LABEL(symtab_nsyms) # save number of symtab
bisl3 $0x80000000,%r9,_C_LABEL(symtab_end)
3: addl3 _C_LABEL(esym),$0x3ff,%r0 # Round symbol table end
bicl3 $0x3ff,%r0,%r1 #
movl %r1,_C_LABEL(lwp0)+L_PCB # lwp0 pcb, XXXuvm_lwp_getuarea
bicl3 $0x80000000,%r1,%r0 # get phys lwp0 uarea addr
mtpr %r0,$PR_PCBB # Save in IPR PCBB
addl3 $USPACE,%r1,%r0 # Get kernel stack top
mtpr %r0,$PR_KSP # put in IPR KSP
movl %r0,_C_LABEL(Sysmap) # SPT start addr after KSP
movl _C_LABEL(lwp0)+L_PCB,%r0 # get PCB virtual address
mfpr $PR_PCBB,PCB_PADDR(%r0) # save PCB physical address
movab PCB_ONFAULT(%r0),ESP(%r0) # Save trap address in ESP
mtpr 4(%r0),$PR_ESP # Put it in ESP also
movl %r1,%r0 # get lwp0 pcb
clrl P0LR(%r0)
clrl P1LR(%r0)
mtpr $0,$PR_P0LR
mtpr $0,$PR_P1LR
movl $0x80000000,%r1
movl %r1,P0BR(%r0)
movl %r1,P1BR(%r0)
mtpr %r1,$PR_P0BR
mtpr %r1,$PR_P1BR
clrl PCB_ONFAULT(%r0)
mtpr $0,$PR_SCBB
#if defined(COMPAT_14)
tstl (%ap) # Any arguments?
bneq 1f # Yes, called from new boot
movl %r11,_C_LABEL(boothowto) # Howto boot (single etc...)
movl %r8,_C_LABEL(avail_end) # Usable memory (from VMB)
clrl -(%sp) # Have no RPB
brb 2f
#endif
1: pushl 4(%ap) # Address of old rpb
2: calls $1,_C_LABEL(_start) # Jump away.
.align 2
.globl _C_LABEL(sigcode),_C_LABEL(esigcode)
_C_LABEL(sigcode):
pushr $0x3f
subl2 $0xc,%sp
movl 0x24(%sp),%r0
calls $3,(%r0)
popr $0x3f
chmk $SYS_compat_16___sigreturn14
chmk $SYS_exit
halt
_C_LABEL(esigcode):
#ifdef COMPAT_ULTRIX
.align 2
.globl _C_LABEL(ultrix_sigcode),_C_LABEL(ultrix_esigcode)
_C_LABEL(ultrix_sigcode):
pushr $0x3f
subl2 $0xc,%sp
movl 0x24(%sp),%r0
calls $3,(%r0)
popr $0x3f
chmk $ULTRIX_SYS_sigreturn
chmk $SYS_exit
halt
_C_LABEL(ultrix_esigcode):
#endif
.align 2
.globl _C_LABEL(idsptch), _C_LABEL(eidsptch)
_C_LABEL(idsptch):
pushr $0x3f
.word 0x9f16 # jsb to absolute address
.long _C_LABEL(cmn_idsptch) # the absolute address
.long 0 # the callback interrupt routine
.long 0 # its argument
.long 0 # ptr to correspond evcnt struct
_C_LABEL(eidsptch):
_C_LABEL(cmn_idsptch):
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
calls $0,_C_LABEL(krnlock)
#endif
movl (%sp)+,%r0 # get pointer to idspvec
mtpr $IPL_VM,$PR_IPL # Make sure we are at IPL_VM
movl 8(%r0),%r1 # get evcnt pointer
beql 1f # no ptr, skip increment
incl EV_COUNT(%r1) # increment low longword
adwc $0,EV_COUNT+4(%r1) # add any carry to hi longword
1: mfpr $PR_SSP, %r2 # get curlwp
movl L_CPU(%r2), %r2 # get curcpu
incl CI_NINTR(%r2) # increment ci_data.cpu_nintr
adwc $0,(CI_NINTR+4)(%r2)
#if 0
pushl %r0
movq (%r0),-(%sp)
pushab 2f
calls $3,_C_LABEL(printf)
movl (%sp)+,%r0
#endif
pushl 4(%r0) # push argument
calls $1,*(%r0) # call interrupt routine
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
calls $0,_C_LABEL(krnunlock)
#endif
popr $0x3f # pop registers
rei # return from interrupt
#if 0
2: .asciz "intr %p(%p)\n"
#endif
ENTRY(badaddr,0) # Called with addr,b/w/l
mfpr $PR_IPL,%r0 # splhigh()
mtpr $IPL_HIGH,$PR_IPL
movl 4(%ap),%r2 # First argument, the address
movl 8(%ap),%r1 # Sec arg, b,w,l
pushl %r0 # Save old IPL
clrl %r3
movab 4f,_C_LABEL(memtest) # Set the return address
caseb %r1,$1,$4 # What is the size
1: .word 1f-1b
.word 2f-1b
.word 3f-1b # This is unused
.word 3f-1b
1: movb (%r2),%r1 # Test a byte
brb 5f
2: movw (%r2),%r1 # Test a word
brb 5f
3: movl (%r2),%r1 # Test a long
brb 5f
4: incl %r3 # Got machine chk => addr bad
5: mtpr (%sp)+,$PR_IPL
movl %r3,%r0
ret
#ifdef DDB
.globl _C_LABEL(setjmp), _C_LABEL(longjmp)
_C_LABEL(setjmp):.word 0
movl 4(%ap), %r0
movl 8(%fp), (%r0)
movl 12(%fp), 4(%r0)
movl 16(%fp), 8(%r0)
moval 28(%fp),12(%r0)
clrl %r0
ret
_C_LABEL(longjmp):.word 0
movl 4(%ap), %r1
movl $1, %r0
movl (%r1), %ap
movl 4(%r1), %fp
movl 12(%r1), %sp
jmp *8(%r1)
#endif
#if defined(MULTIPROCESSOR)
.align 2
.globl _C_LABEL(vax_mp_tramp) # used to kick off multiprocessor systems.
_C_LABEL(vax_mp_tramp):
ldpctx
rei
#endif
.globl softint_cleanup,softint_exit,softint_process
.type softint_cleanup@function
.type softint_exit@function
.type softint_process@function
softint_cleanup:
movl L_CPU(%r0),%r1
incl CI_MTX_COUNT(%r1)
movl L_PCB(%r0),%r1
softint_exit:
popr $0x3
rei
softint_process:
movq %r6,-(%sp)
calls $2,_C_LABEL(softint_dispatch)
movl L_PCB(%r6),%r3
movab softint_exit,PCB_PC(%r3)
#ifdef MULTIPROCESSOR
movl L_CPU(%r6),%r8
movl %r6,CI_CURLWP(%r8)
#endif
mfpr $PR_SSP,%r4
movl L_PCB(%r4),%r4
movl P0LR(%r4),%r0
movl P0LR(%r3),%r1
cmpl %r0,%r1
bgtru 1f
extv $24,$3,%r0,%r0
insv %r0,$24,$3,P0LR(%r3)
insv $4,$24,$3,P0LR(%r4)
1:
mtpr PCB_PADDR(%r3),$PR_PCBB
ldpctx
rei
softint_common:
mfpr $PR_IPL,%r1
mtpr $IPL_HIGH,$PR_IPL
movpsl -(%sp)
pushab softint_cleanup
svpctx
mfpr $PR_SSP,%r6
movl L_CPU(%r6),%r8
movl CI_SOFTLWPS(%r8)[%r0],%r2
movl L_PCB(%r2),%r3
movl %r6,PCB_R6(%r3)
movl %r1,PCB_R7(%r3)
#ifdef MULTIPROCESSOR
movl %r2,CI_CURLWP(%r8)
#endif
movab (USPACE-TRAPFRAMELEN-CALLSFRAMELEN)(%r3),%r0
movl %r0,KSP(%r3)
movl %r0,PCB_FP(%r3)
movab CA_ARGNO(%r0),PCB_AP(%r3)
movab softint_process,PCB_PC(%r3)
movl $PSL_HIGHIPL,PCB_PSL(%r3)
mtpr PCB_PADDR(%r3),$PR_PCBB
ldpctx
rei
SCBENTRY(softclock)
pushr $0x3
movl $SOFTINT_CLOCK,%r0
brb softint_common
SCBENTRY(softbio)
pushr $0x3
movl $SOFTINT_BIO,%r0
brb softint_common
SCBENTRY(softnet)
pushr $0x3
movl $SOFTINT_NET,%r0
brb softint_common
SCBENTRY(softserial)
pushr $0x3
movl $SOFTINT_SERIAL,%r0
brb softint_common
ENTRY(cpu_lwp_bootstrap, 0)
movq %r2,-(%sp)
movq %r0,-(%sp)
calls $2,_C_LABEL(lwp_startup)
movl (%sp)+,%r0
calls $1,(%r0)
ret
JSBENTRY(Swtchto)
svpctx # Now on interrupt stack
movl L_PCB(%r1),%r3 # Get pointer to new pcb.
movl %r0,PCB_R0(%r3) # move r0 into new pcb (return value)
#ifdef MULTIPROCESSOR
movl L_CPU(%r0), %r8
movl %r8, L_CPU(%r1)
movl %r1,CI_CURLWP(%r8)
#endif
mtpr PCB_PADDR(%r3),$PR_PCBB # set PA of new pcb
mtpr $IPL_HIGH,$PR_IPL
ldpctx # load it
rei
#
#
ENTRY(copyout, 0)
movl 8(%ap),%r3
blss 3f # kernel space
movl 4(%ap),%r1
brb 2f
ENTRY(copyin, 0)
movl 4(%ap),%r1
blss 3f # kernel space
movl 8(%ap),%r3
2: mfpr $PR_ESP,%r2
movab 1f,(%r2) # set pcb_onfault
4: tstw 14(%ap) # check if >= 64K
bneq 5f
movc3 12(%ap),(%r1),(%r3)
clrl %r0
1: mfpr $PR_ESP,%r2
clrl (%r2) # clear pcb_onfault
ret
5: movc3 $0xfffc,(%r1),(%r3)
subl2 $0xfffc,12(%ap)
brb 4b
3: movl $EFAULT,%r0
ret
ENTRY(kcopy,0)
mfpr $PR_ESP,%r3
movl (%r3),-(%sp) # save current pcb_onfault
movab 1f,(%r3) # set pcb_onfault
movl 4(%ap),%r1
movl 8(%ap),%r2
movc3 12(%ap),(%r1), (%r2)
clrl %r0
1: mfpr $PR_ESP,%r3
movl (%sp)+,(%r3) # restore pcb_onfault
ret
ENTRY(copyinstr, 0)
tstl 4(%ap) # kernel address?
bgeq 8f # no, continue
6: movl $EFAULT,%r0
movl 16(%ap),%r2
beql 7f
clrl (%r2)
7: ret
ENTRY(copyoutstr, 0)
tstl 8(%ap) # kernel address?
bgeq 8f # no, continue
brb 6b # yes, return EFAULT
8: movl 4(%ap),%r5 # from
movl 8(%ap),%r4 # to
movl 12(%ap),%r3 # len
movl 16(%ap),%r2 # copied
clrl %r0
mfpr $PR_ESP,%r1
movab 2f,(%r1) # set pcb_onfault
tstl %r3 # any chars to copy?
bneq 1f # yes, jump for more
0: tstl %r2 # save copied len?
beql 2f # no
subl3 4(%ap),%r5,(%r2) # save copied len
2: mfpr $PR_ESP,%r1
clrl (%r1) # clear pcb_onfault
ret
1: movb (%r5)+,(%r4)+ # copy one char
beql 0b # jmp if last char
sobgtr %r3,1b # copy one more
movl $ENAMETOOLONG,%r0 # inform about too long string
brb 0b # out of chars
.align 2
#define UFETCHSTORE_PROLOGUE \
tstl 4(%ap) ;\
blss 1f ;\
mfpr $PR_ESP,%r1 ;\
movab 2f,(%r1)
#define UFETCHSTORE_EPILOGUE \
mfpr $PR_ESP,%r1 ;\
clrl (%r1)
#define UFETCHSTORE_RETURN \
clrl %r0 ;\
ret ;\
1: movl $EFAULT,%r0 ;\
ret ;\
2: UFETCHSTORE_EPILOGUE ;\
ret
ENTRY(_ufetch_8,0)
UFETCHSTORE_PROLOGUE
movb *4(%ap),*8(%ap) # *valp = *uaddr
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
ENTRY(_ufetch_16,0)
UFETCHSTORE_PROLOGUE
movw *4(%ap),*8(%ap) # *valp = *uaddr
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
ENTRY(_ufetch_32,0)
UFETCHSTORE_PROLOGUE
movl *4(%ap),*8(%ap) # *valp = *uaddr
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
ENTRY(_ustore_8,0)
UFETCHSTORE_PROLOGUE
movb 8(%ap),*4(%ap) # *uaddr = val
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
ENTRY(_ustore_16,0)
UFETCHSTORE_PROLOGUE
movw 8(%ap),*4(%ap) # *uaddr = val
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
ENTRY(_ustore_32,0)
UFETCHSTORE_PROLOGUE
movl 8(%ap),*4(%ap) # *uaddr = val
UFETCHSTORE_EPILOGUE
UFETCHSTORE_RETURN
.align 2
JSBENTRY(Slock)
1: bbssi $0,(%r1),1b
rsb
JSBENTRY(Slocktry)
clrl %r0
bbssi $0,(%r1),1f
incl %r0
1: rsb
JSBENTRY(Sunlock)
bbcci $0,(%r1),1f
1: rsb
#
#
.data
.globl _C_LABEL(memtest)
_C_LABEL(memtest): # memory test in progress
.long 0