/
/	SCCS id	@(#)M.s	1.7 (Berkeley)	7/11/83
/
/ Startup code for two-stage bootstrap
/ With support for UCB_AUTOBOOT
/ Supports 11/40, 11/45, 11/70, 11/23, 11/23+I/O map (11/24)
/ and similar machines

/ non-UNIX instructions
mfpi	= 6500^tst
stst	= 170300^tst
mtpi	= 6600^tst
mfpd	= 106500^tst
mtpd	= 106600^tst
spl	= 230
ldfps	= 170100^tst
stfps	= 170200^tst
wait	= 1
rtt	= 6
halt	= 0
reset	= 5
systrap = 104400

/  The boot options and device are placed in the last SZFLAGS bytes
/  at the end of core by the kernel if this is an autoboot.
/  The first-stage boot will leave them in registers for us;
/  we clobber possible old flags so that they don't get re-used.
ENDCORE=	160000		/ end of core, mem. management off
SZFLAGS=	6		/ size of boot flags
BOOTOPTS=	2		/ location of options, bytes below ENDCORE
BOOTDEV=	4
CHECKWORD=	6

.globl	_end
.globl	_main,_ubmapset
	jmp	start

/
/ trap vectors
/
	trap;340	/ bus error -- grok!
	trap;341	/ illegal instruction
	trap;342	/ BPT
	trap;343	/ IOT
	trap;344	/ POWER FAIL
	trap;345	/ EMT
tvec:
	start;346	/ TRAP
.=400^.


start:
	reset
	mov	$340,PS
	mov	$140100,sp

/save boot options, if present
	mov	r4,_bootopts
	mov	r3,_bootdev
	mov	r2,_checkword
/clobber any boot flags left in memory
	clr	ENDCORE-BOOTOPTS
	clr	ENDCORE-BOOTDEV
	clr	ENDCORE-CHECKWORD
/
/ determine what kind of cpu we are running on
/ first, check switches. if they are 40, 24, 45 or 70
/ set appropriately
/
	clrb	_sep_id
	clrb	_ubmap
	clrb	_haveCSW
	mov	$2f,nofault	/ check if we even have switches!
	tst	*$SWREG
	clr	nofault		/ apparently we do
	incb	_haveCSW
	mov	$40.,r0
	cmp	*$SWREG,$40
	beq	gotcha
	cmp	*$SWREG,$24
	bne	1f
	mov	$24.,r0
	incb	_ubmap
	jbr	gotcha
1:
	cmp	*$SWREG,$45
	bne	1f
	mov	$45.,r0
	incb	_sep_id
	jbr	gotcha
1:
	cmp	*$SWREG,$70
	bne	2f
	mov	$70.,r0
	incb	_sep_id
	incb	_ubmap
	jbr	gotcha
/
/ if we can't find out from switches,
/ explore and see what we find
/
2:
	mov	$40.,r0		/ assume 11/40
	mov	$2f,nofault
	mov	*$KDSA6,r1	/ then we have sep i/d
	incb	_sep_id
	mov	$45.,r0
	mov	$1f,nofault
	mov	*$UBMAP,r1	/ then we have a unibus map
	incb	_ubmap
	mov	$70.,r0
	br	1f
2:
	mov	$1f,nofault
	mov	*$UBMAP,r1	/ then we have a unibus map
	incb	_ubmap
	mov	$24.,r0		/ unibus map, no sep. I/D = 24
1:	clr	nofault
gotcha:
	mov	r0,_cputype

/
/	Set kernel I space registers to physical 0 and I/O page
/
	clr	r1
	mov	$77406, r2
	mov	$KISA0, r3
	mov	$KISD0, r4
	jsr	pc, setseg
	mov	$IO, -(r3)

/
/	Set user I space registers to physical 128kb and I/O page
/
	mov	$4000, r1	/ 04000 = 128*1024/64
	mov	$UISA0, r3
	mov	$UISD0, r4
	jsr	pc, setseg
	mov	$IO, -(r3)

/
/	If 11/40 class processor, only need set the I space registers
/
	tstb	_sep_id
	jeq	1f

/
/	Set kernel D space registers to physical 0 and I/O page
/
	clr	r1
	mov	$KDSA0, r3
	mov	$KDSD0, r4
	jsr	pc, setseg
	mov	$IO, -(r3)

/
/	Set user D space registers to physical 128kb and I/O page
/
	mov	$4000, r1	/ 04000 = 128*1024/64
	mov	$UDSA0, r3
	mov	$UDSD0, r4
	jsr	pc, setseg
	mov	$IO, -(r3)

1:
/ enable map
	clrb	_ksep
	tstb	_ubmap
	beq	2f
	jsr	pc,_ubmapset
	tstb	_sep_id
	bne	3f
	mov	$60,SSR3	/ 22-bit map, no separation
	br	1f
3:
	mov	$65,SSR3	/ 22-bit map, sep. I/D user and kernel
	movb	$1,_ksep
	cmp	_cputype,$70.
	jne	1f
	mov	$3,MSCR
	br	1f
2:
	tstb	_sep_id		/ no ubmap; sep_id?
	beq	1f
	mov	$5,SSR3
	movb	$1,_ksep
1:
	mov	$30340,PS
	inc	SSR0


/ copy program to user I space
	mov	$_end,r0
	asr	r0
	clr	r1
1:
	mov	(r1),-(sp)
	mtpi	(r1)+
	sob	r0,1b


/ continue execution in user space copy
	mov	$140004,sp
	tstb	_sep_id
	bne	1f
	clr	*$KISA6
	br	2f
1:
	clr	*$KDSA6
2:	mov	$140340,-(sp)
	mov	$user,-(sp)
	rtt
user:
/ clear bss
	mov	$_edata,r0
	mov	$_end,r1
	sub	r0,r1
	inc	r1
	clc
	ror	r1
1:
	clr	(r0)+
	sob	r1,1b
	mov	$_end+512.,sp
	mov	sp,r5

	jsr	pc,_main
	mov	_cputype,r0
	mov	_bootopts,r4
	mov	r4,r2
	com	r2		/ checkword
	systrap

	br	user

setseg:
	mov	$8,r0
1:
	mov	r1,(r3)+
	add	$200,r1
	mov	r2,(r4)+
	sob	r0,1b
	rts	pc

.globl	_setseg
_setseg:
	mov	2(sp),r1
	mov	r2,-(sp)
	mov	r3,-(sp)
	mov	r4,-(sp)
	mov	$77406,r2
	mov	$KISA0,r3
	mov	$KISD0,r4
	jsr	pc,setseg
	tstb	_ksep
	bne	1f
	mov	$IO,-(r3)
1:
	mov	(sp)+,r4
	mov	(sp)+,r3
	mov	(sp)+,r2
	rts	pc

.globl	_setnosep
_setnosep:
	bic	$4,SSR3	/ turn off kernel i/d sep
	clrb	_ksep
	rts pc

.globl	_setsep
_setsep:
	bis	$4,SSR3	/ turn on kernel i/d sep (if not already)
	movb	$1,_ksep
	rts pc

/  Relocate higher in memory for large kernel.
.globl	_reloc, _segflag
_reloc:
	jsr	r5, csv
	mov	$2f, nofault
	/  Set Kernel I to point to new area
	mov	$6000, r1			/ 192 KB
	mov	$77406,r2
	mov	$KISA0, r3
	mov	$KISD0, r4
	jsr	pc, setseg
	/  Copy to new area
	clr	r0
	mov	$28.*1024., r1			/ 28 K words
1:
	mov	(r0), -(sp)
	mtpi	(r0)+
	sob	r1, 1b
	clr	nofault

	/  Repoint kernel I at 0.
	clr	-(sp)
	jsr	pc, _setseg
	tst	(sp)+

	/  Point User D at new area
	tstb	_sep_id
	beq	1f
	mov	$6000, r1			/ 192 KB
	mov	$UDSA0, r3
	mov	$UDSD0, r4
	jsr	pc, setseg
	mov	$IO, -(r3)

	/  Now User I-- execution switches to new copy.
1:
	mov	$6000, r1			/ 192 KB
	mov	$UISA0, r3
	mov	$UISD0, r4
	mov	$7,r0
1:
	mov	r1,(r3)+
	add	$200,r1
	mov	r2,(r4)+
	sob	r0,1b

	mov	$3, _segflag			/ new extension bits
	clr	r0				/ success
	jmp	cret

	/  Trap here on bus error (not enough memory)
2:
	mov	$-1, r0
	jmp	cret

/ clrseg(addr,count)
.globl	_clrseg
_clrseg:
	mov	4(sp),r0
	beq	2f
	asr	r0
	bic	$!77777,r0
	mov	2(sp),r1
1:
	clr	-(sp)
	mtpi	(r1)+
	sob	r0,1b
2:
	rts	pc


/ mtpd(word,addr)
.globl	_mtpd
_mtpd:
	mov	4(sp),r0
	mov	2(sp),-(sp)
	mtpd	(r0)+
	rts	pc

/ mtpi(word,addr)
.globl	_mtpi
_mtpi:
	mov	4(sp),r0
	mov	2(sp),-(sp)
	mtpi	(r0)+
	rts	pc

.globl	__rtt
__rtt:
	halt

.globl	_trap

trap:
	mov	*$PS,-(sp)
	mov	r0,-(sp)
	mov	r1,-(sp)
	tst	nofault
	bne	3f
	jsr	pc,_trap
	mov	(sp)+,r1
	mov	(sp)+,r0
	tst	(sp)+
	rtt
3:	mov	(sp)+,r1
	mov	(sp)+,r0
	tst	(sp)+
	mov	nofault,(sp)
	rtt

PS	= 177776
SSR0	= 177572
SSR1	= 177574
SSR2	= 177576
SSR3	= 172516
KISA0	= 172340
KISA1	= 172342
KISA6	= 172354
KISA7	= 172356
KISD0	= 172300
KISD7	= 172316
KDSA0	= 172360
KDSA6	= 172374
KDSA7	= 172376
KDSD0	= 172320
KDSD5	= 172332
SISA0	= 172240
SISA1	= 172242
SISD0	= 172200
SISD1	= 172202
UISA0	= 177640
UISD0	= 177600
UDSA0	= 177660
UDSD0	= 177620
MSCR	= 017777746	/ 11/70 memory control register
IO	= 177600
SWREG	= 177570
UBMAP	= 170200


.data
.globl	_cputype
.globl	_ksep, _sep_id, _ubmap, _haveCSW
.globl	_bootopts, _bootdev, _checkword

nofault:	.=.+2	/ where to go on predicted trap
_cputype:	.=.+2	/ cpu type (currently 40,45 or 70)
_sep_id:	.=.+1	/ 1 if we have separate I and D
_ubmap:		.=.+1	/ 1 if we have a unibus map
_haveCSW:	.=.+1	/ 1 if we have a console switch register
_ksep:		.=.+1	/ 1 if kernel mode has sep I/D enabled
_bootopts:	.=.+2	/ flags if an autoboot
_bootdev:	.=.+2	/ device to get unix from, if not RB_ASKNAME
_checkword:	.=.+2	/ saved r2, complement of bootopts if an autoboot
