⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locore.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
 * *  2 Jan 84 --jmcg *	Added support for MicroVAX 1. * *************************************************************************/#include "../h/param.h"#include "../machine/psl.h"#include "../machine/pte.h"#include "../h/errno.h"#include "../h/cmap.h"#include "../h/cpudata.h"#include "../h/kmalloc.h"#include "../machine/mtpr.h"#include "../machine/pcb.h"#include "../machine/trap.h"#include "../machine/cpu.h"#include "../../machine/common/cpuconf.h"#include "../machine/b_params.h"#include "../machine/cons.h"#include "../machine/clock.h"#include "../io/bi/bireg.h"/*#include "../machine/nexus.h"#include "../io/uba/ubareg.h"*/#include "../machine/sas/vmb.h"#include "../h/smp_lock.h"#include "dh.h"#include "dz.h"#include "ss.h"#include "fc.h"#include "uu.h"#include "ps.h"#include "mba.h"#include "ci.h"#include "msi.h"#define	is_vect_inst 0#define	isnt_vect_inst 1#define	ENTRY(name, regs) \ 	.globl _/**/name; .align 1; _/**/name: .word regs#define R0 0x01#define R1 0x02#define R2 0x04#define R3 0x08#define R4 0x10#define R5 0x20#define R6 0x40	.set	INTSTK,1	# handle this interrupt on the interrupt stack	.set	HALT,3		# halt if this interrupt occurs	.set	HIGH,0x1f	# mask for total disable	.set	MCKVEC,4	# offset into scb of machine check vector	.set	VPN_WIDTH,21	.set	SYSPROC,10	# system process priority level/* * User structure is UPAGES at top of user space. */	.globl	_u	.set	_u,0x80000000 - UPAGES*NBPG	.globl	_forkutl	.set	_forkutl,_u - FORKPAGES*NBPG	.globl	_intstack	.globl  _eintstack/* * Do a dump. * Called by auto-restart. * May be called manually. */	.align	2	.globl	_doadump_doadump:	nop; nop				# .word 0x0101#define _rpbmap _Sysmap 			# rpb, scb, UNI*vec, istack*4	bicl2	$PG_PROT,_rpbmap	bisl2	$PG_KW,_rpbmap	mtpr	$0,$TBIA	bitl	$2,_rpb+RP_FLAG			# dump only once!	bneq	1f	bisl2	$2,_rpb+RP_FLAG	movl	sp,_edumpstack	movab	_edumpstack,sp	mtpr 	sp,$ISP	mfpr	$PCBB,-(sp)	mfpr	$MAPEN,-(sp)	mfpr	$IPL,-(sp)	cmpl    $V_VAX,_cpu             	# Are we a Virtual VAX?	bneq    2f				# no: go to normal dump	calls	$0,_vvaxdump			# yes	brb     1f2:	mtpr	$HIGH,$IPL	mtpr	$0,$MAPEN	pushr	$0x3fff	calls	$0,_dumpsys1:	pushl	$TXDB_BOOT			# reboot the system	calls	$1,_cons_putc			# let cons_putc tell the console						# (it handles VAX 8600)	halt					# come back and halt/* * Where called	: qioinit is called in the generic dump driver. * Function	: Called to initialize the dump device. * Parameters	: None. * Side effects	: Computes global variable _qioentry, the entry point *		  into the qio routine of the new boot driver. */	.globl	_qioinit_qioinit:	.word	0xffc				# save r2 - r11	movl	_vmbinfo,r8			# r8 points to info list	movl	INFO_RPBBAS(r8),r9		# required bu init routines	movl	INFO_BTDRBAS(r8),r7		# get address of boot driver	addl3	r7,BQO$L_QIO(r7),_qioentry	# compute address qio routine	movl	$1,r0				# in case no init routine.	tstl	BQO$L_UNIT_INIT(r7)		# does init routine exist ?	beql	4f				# if not dont bother trying	addl3	r7,BQO$L_UNIT_INIT(r7),r2	# calculate entry point/* * KLUDGE (for [T]MSCP controller types) to force total controller * initialization, otherwise we wait an awful long time for * initialization to complete. Also used to set up driver rings to * talk to VMB, not UFS. */#define	IP	0#define	SA	2	cmpb	$BTD$K_UDA,RPB$B_DEVTYP(r9)	# is this a uda/qda/kda ?	beql	1f				# yes, go hit it	cmpb	$BTD$K_TK50,RPB$B_DEVTYP(r9)	# is this a TK50 controller ?	beql	1f				# yes, go hit it	brb	2f				# proceed with normal init1:	movl	RPB$L_CSRPHY(r9),r7		#get the IP register address	clrw	IP(r7)				# poke it to make it step1:	movw	SA(r7),r0			# get the status register	bitw	$0xfe00,SA(r7)			# is something active ?	beql	1b				# if not, wait until there is2:	mfpr	$SCBB,r7			# required by BI (BDA driver)	callg	*INFO_VMBARGBAS(r8),(r2)	# do it4:	ret/* * Where called	: qiois called in the generic dump driver. * Function	: Called to perform reading from core and writing to *		  the dump device. * Parameters	: 1) Address mode, physical or virtual. *		  2) Function, reading or writing virtual/physical space. *		  3) Starting block number, starting disk block number. *		  4) Transfer size, in bytes. *		  5) Address of buffer, memory location. * Side effects	: Performs io function and returns completion code. */	.globl _qio_qio:	.word	0xe00				# save r9 - r11	movl	_vmbinfo,r9			# point to the info list	movl	INFO_RPBBAS(r9),r9		# get address of the RPB	pushl	r9				# push address of RPB	pushl	4(ap)				# push address mode	pushl	8(ap)				# push I/O function code	pushl	12(ap)				# push starting block number	pushl	16(ap)				# push transfer size in bytes	pushl	20(ap)				# push address of buffer	calls	$6,*_qioentry			# call qio routine	ret					# return completion code#ifdef VVAX/* * These two functions are versions of qio and qioinit which run with * Virtual Memory turned on. This is required by VVAX. *//* * Where called	: v_qioinit is called in the generic dump driver. * Function	: Called to initialize the dump device. * Parameters	: None. * Side effects	: Computes global variable _qioentry, the entry point *		  into the qio routine of the new boot driver. */	.globl	_v_qioinit_v_qioinit:	.word	0xffc				# save r2 - r11	moval	_vmb_info,r8			# r8 points to info list	moval	_rpb,r9				# required by init routines	movl	INFO_BTDRBAS(r8),r7		# get address of boot driver	subl2	_vmbinfo,r7			# now convert to virtual	addl2	r8,r7				# address	addl3	r7,BQO$L_QIO(r7),_qioentry	# compute address qio routine	movl	$1,r0				# in case no init routine.	tstl	BQO$L_UNIT_INIT(r7)		# does init routine exist ?	beql	1f				# if not dont bother trying	addl3	r7,BQO$L_UNIT_INIT(r7),r2	# calculate entry point		movl	INFO_VMBARGBAS(r8),r7		# get address of arg list	subl2	_vmbinfo,r7			# now convert to virtual	addl2	r8,r7				# address	callg	(r7),(r2)			# do it1:	ret/* * Where called	: v_qio is called in the generic dump driver. * Function	: Called to perform reading from core and writing to *		  the dump device. * Parameters	: 1) Address mode, physical or virtual. *		  2) Function, reading or writing virtual/physical space. *		  3) Starting block number, starting disk block number. *		  4) Transfer size, in bytes. *		  5) Address of buffer, memory location. * Side effects	: Performs io function and returns completion code. */	.globl _v_qio_v_qio:	.word	0xe00				# save r9 - r11	pushal	_rpb				# push address of RPB	pushl	4(ap)				# push address mode	pushl	8(ap)				# push I/O function code	pushl	12(ap)				# push starting block number	pushl	16(ap)				# push transfer size in bytes	pushl	20(ap)				# push address of buffer	calls	$6,*_qioentry			# call qio routine	ret					# return completion code#endif VVAX/* * {fu,su},{byte,word}, all massaged by asm.sed to jsb's */	.globl	_Fuword_Fuword:	prober	$3,$4,(r0)	beql	fserr	movl	(r0),r0	rsbfserr:	mnegl	$1,r0	rsb	.globl	_Fubyte_Fubyte:	prober	$3,$1,(r0)	beql	fserr	movzbl	(r0),r0	rsb	.globl	_Suword_Suword:	probew	$3,$4,(r0)	beql	fserr	movl	r1,(r0)	clrl	r0	rsb	.globl	_Subyte_Subyte:	probew	$3,$1,(r0)	beql	fserr	movb	r1,(r0)	clrl	r0	rsb/* * Check address. * Given virtual address, byte count, and rw flag * returns 0 on no access. */_useracc:	.globl	_useracc	.word	0x0	movl	4(ap),r0		# get va	movl	8(ap),r1		# count	tstl	12(ap)			# test for read access ?	bneq	userar			# yes	cmpl	$NBPG,r1			# can we do it in one probe ?	bgeq	uaw2			# yesuaw1:	probew	$3,$NBPG,(r0)	beql	uaerr			# no access	addl2	$NBPG,r0	acbl	$NBPG+1,$-NBPG,r1,uaw1uaw2:	probew	$3,r1,(r0)	beql	uaerr	movl	$1,r0	retuserar:	cmpl	$NBPG,r1	bgeq	uar2uar1:	prober	$3,$NBPG,(r0)	beql	uaerr	addl2	$NBPG,r0	acbl	$NBPG+1,$-NBPG,r1,uar1uar2:	prober	$3,r1,(r0)	beql	uaerr	movl	$1,r0	retuaerr:	clrl	r0	ret_addupc:	.globl	_addupc	.word	0x0	movl	8(ap),r2		# &u.u_prof	subl3	8(r2),4(ap),r0		# corrected pc	blss	9f	extzv	$1,$31,r0,r0		# logical right shift	extzv	$1,$31,12(r2),r1	# ditto for scale	emul	r1,r0,$0,r0	ashq	$-14,r0,r0	tstl	r1	bneq	9f	bicl2	$1,r0	cmpl	r0,4(r2)		# length	bgequ	9f	addl2	(r2),r0 		# base	probew	$3,$2,(r0)	beql	8f	addw2	12(ap),(r0)9:	ret8:	clrl	12(r2)	ret /* * Copy a null terminated string from the user address space into * the kernel address space. * * copyinstr(fromaddr, toaddr, maxlength, &lencopied) */ENTRY(copyinstr, R6) 	movl	12(ap),r6		# r6 = max length 	jlss	8f 	movl	4(ap),r1		# r1 = user address 	bicl3	$~(NBPG*CLSIZE-1),r1,r2	# r2 = bytes on first page 	subl3	r2,$NBPG*CLSIZE,r2 	movl	8(ap),r3		# r3 = kernel address1: 	cmpl	r6,r2			# r2 = min(bytes on page, length left);	jgeq	2f	movl	r6,r22:	prober	$3,r2,(r1)		# bytes accessible?	jeql	8f	subl2	r2,r6			# update bytes left count	locc	$0,r2,(r1)		# null byte found?	jneq	3f	subl2	r2,r1			# back up pointer updated by `locc'	movc3	r2,(r1),(r3)		# copy in next piece	movl	$(NBPG*CLSIZE),r2	# check next page	tstl	r6			# run out of space?	jneq	1b	movl	$ENAMETOOLONG,r0	# set error code and return	jbr	9f3:	tstl	16(ap)			# return length?	beql	4f	subl3	r6,12(ap),r6		# actual len = maxlen - unused pages	subl2	r0,r6			#	- unused on this page	addl3	$1,r6,*16(ap)		#	+ the null byte4: 	subl2	r0,r2			# r2 = number of bytes to move	subl2	r2,r1			# back up pointer updated by `locc'	incl	r2			# copy null byte as well	movc3	r2,(r1),(r3)		# copy in last piece	clrl	r0			# redundant	ret8:	movl	$EFAULT,r09:	tstl	16(ap)	beql	1f 	subl3	r6,12(ap),*16(ap)1:	ret/* * Copy a null terminated string from the kernel * address space to the user address space. * * copyoutstr(fromaddr, toaddr, maxlength, &lencopied) */ENTRY(copyoutstr, R6)	movl	12(ap),r6		# r6 = max length	jlss	8b	movl	4(ap),r1		# r1 = kernel address	movl	8(ap),r3		# r3 = user address	bicl3	$~(NBPG*CLSIZE-1),r3,r2	# r2 = bytes on first page	subl3	r2,$NBPG*CLSIZE,r21:	cmpl	r6,r2			# r2 = min(bytes on page, length left);	jgeq	2f	movl	r6,r22:	probew	$3,r2,(r3)		# bytes accessible?	jeql	8b	subl2	r2,r6			# update bytes left count	locc	$0,r2,(r1)		# null byte found?	jneq	3b	subl2	r2,r1			# back up pointer updated by `locc'	movc3	r2,(r1),(r3)		# copy in next piece	movl	$(NBPG*CLSIZE),r2	# check next page	tstl	r6			# run out of space?	jneq	1b	movl	$ENAMETOOLONG,r0	# set error code and return	jbr	9b/* * Copy a null terminated string from one point to another in * the kernel address space. * * copystr(fromaddr, toaddr, maxlength, &lencopied) */ENTRY(copystr, R6)	movl	12(ap),r6		# r6 = max length	jlss	8b	movl	4(ap),r1		# r1 = src address	movl	8(ap),r3		# r3 = dest address1:	movzwl	$65535,r2		# r2 = bytes in first chunk	cmpl	r6,r2			# r2 = min(bytes in chunk, length left);	jgeq	2f	movl	r6,r22:	subl2	r2,r6			# update bytes left count	locc	$0,r2,(r1)		# null byte found?	jneq	3b	subl2	r2,r1			# back up pointer updated by `locc'	movc3	r2,(r1),(r3)		# copy in next piece	tstl	r6			# run out of space?	jneq	1b	movl	$ENAMETOOLONG,r0	# set error code and return	jbr	9b/* * Copy specified amount of data from user space into the kernel * Copyin(from, to, len) *	r1 == from (user source address) *	r3 == to (kernel destination address) *	r5 == length */	.globl	_Copyin 		# massaged to jsb, args R1 R3 R5_Copyin:#ifdef SMP_DEBUG	tstl	_smp_debug	beql	1f	pushr	$0x3f	calls	$0,_sleep_check	popr	$0x3f1:#endif	cmpl	r5,$(NBPG*CLSIZE)	# probing one page or less ?	bgtru	1f			# no	prober	$3,r5,(r1)		# bytes accessible ?	beql	ersb			# no	movc3	r5,(r1),(r3)/*	clrl	r0			# redundant */	rsb1:	blss	ersb			# negative length?	pushl	r6			# r6 = length	movl	r5,r6	bicl3	$~(NBPG*CLSIZE-1),r1,r0 # r0 = bytes on first page	subl3	r0,$(NBPG*CLSIZE),r0	addl2	$(NBPG*CLSIZE),r0	# plus one additional full page	jbr	2fciloop:	movc3	r0,(r1),(r3)	movl	$(2*NBPG*CLSIZE),r0	# next amount to move2:	cmpl	r0,r6

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -