BSD 4 development
[unix-history] / .ref-BSD-3 / usr / mdec / uboot.s
CommitLineData
cd124064
BJ
1#
2# RP06/RM03 disk boot program to load "/boot" from
3# a UNIX filesystem (starting at block 1 on pack on
4# drive 0) into low core and to execute that file.
5# This program can only read regular small version 7 files
6# from the root of a UNIX filesystem.
7#
8#
9 .set BLKSIZ,1024 # disc block size
10 .set RELOC,0x50000
11 .set HDRSIZ,040
12 .set INOSIZ,64 # no. bytes/inode entry
13 .set INOBLK,BLKSIZ/INOSIZ # no. inodes/disc block
14 .set INOMSK,0xfffffff0 # changes with inode size
15 .set NAMSIZ,14 # no. bytes in name field of dir entry
16 .set ENTADR,024 # offset to entry addr in task header
17 .set DIRSIZ,16 # size of directory entry, bytes
18 .set ROOTINO,2 # root dir inode no.
19 .set NBOO,1
20 .set NSUP,1
21 .set SLASH,057 # '/'
22# MBA registers
23 .set MBA0,0x20010000 # MBA 0 device reg's
24 .set M_cr,MBA0+4 # MBA control reg
25 .set M_var,MBA0+12 # MBA virt addr reg
26 .set M_bc,MBA0+16 # MBA byte count reg
27 .set M_map,MBA0+0x800 # start of MBA map reg's
28 .set MBAinit,1 # MBA init bit in MBA control reg
29#
30 .set RM3SEC,32
31 .set RM3TRK,5
32 .set RP6typ,022
33 .set RM3typ,024
34#
35 .set RP6TRK,19
36 .set RP6SEC,22
37 .set RP,MBA0+0x400 # start of RP06 drive 0 reg's
38 .set RP_cr,RP+0 # RP06 control reg, drive 0
39 .set RP_sr,RP+4 # status reg
40 .set RP_stk,RP+0x14 # desired track/sector reg
41 .set RP_dt,RP+0x18 # drive type reg
42 .set RP_off,RP+0x24 # RP offset reg
43 .set RP_cyl,RP+0x28 # desired cyl reg
44# RP06 function codes, status bits
45 .set RP_GO,1 # GO bit
46 .set RP_RED,070 # read data
47 .set RP_DC,010 # drive clear function code
48 .set RP_RIP,020 # Read-In Preset function code
49 .set RP_FMT,0x1000 # format bit for offset reg
50 .set RP_MOL,0x1000 # medium online in status reg
51 .set RP_DRY,0200 # drive ready, staus reg
52 .set RP_ERR,040000 # composite error, staus reg
53 .set RP_pDRY,7 # bit position of RP_DRY
54 .set RP_pERR,14 # bit position of RP_ERR
55#
56#
57init :
58# system initialization - executed once per boot load
59 halt # entry mask required by DEC monitor software
60 halt
61 movl $MBAinit,*$M_cr # MBA initialize
62 movl $RP_RIP+RP_GO,*$RP_cr # read-in preset
63 movl $RP_FMT,*$RP_off # format bit in RP offset reg
64#
65 movl *$RP_dt,r0
66 cmpb $RP6typ,r0
67 bneq rm3
68 movl $RP6SEC,*$rpsec
69 movl $RP6TRK,*$rptrk
70 brb domul
71rm3:
72 movl $RM3SEC,*$rpsec
73 movl $RM3TRK,*$rptrk
74domul:
75 mull3 *$rpsec,*$rptrk,*$rpst
76# move boot image up to higher core
77start :
78 movl $RELOC,sp
79# 'uboot' must have no header
80 movc3 $end,*$0,(sp) # move boot to relocated position
81#
82# jump to re-located code at 'start2' - done once per boot load
83 jmp *$RELOC+start2
84#
85# execution starts here only after boot has been re-located
86start2 :
87#
88# search inodes for pathname specified in 'names'
89#
90# Must preserve r6 & r7
91# 'cmpc[35]' instruction uses reg's 0 - 3
92# 'movc[35]' instruction uses reg's 0-5
93 movl $names+RELOC,r6 # start of input filename
94 movzbl $ROOTINO,r0 # start at root inode for search
95nxti :
96 clrw *$bno # 'bno' is index into 'iaddr[]' in inode entry
97 bsbw iget # get inode into core
98 tstb (r6) # r6 -> empty pathname component if end of pathname
99 beql getfil
100get1b :
101 bsbw rmblk # read in 1 of blocks in 'addr[]' in inode entry
102 beql start2 # file not found if zero cc set
103#
104 movl $buf,r7 # buffer holds directory block
105nxtent :
106 tstw (r7) # null dir entry (inode # field = 0)
107 beql dirchk
108 cmpc3 $NAMSIZ,(r6),2(r7) # compare 'names' against
109# dir entry - both null-filled
110 bneq dirchk # branch if dir entry is not the one
111# found component in a dir entry
112 movzwl (r7),r0 # 2-byte inode no. from 1st 2 bytes of dir entry
113 addl2 $NAMSIZ,r6 # point to next pathname component in 'names[]'
114 brb nxti # now go get inode whose no. is in r0
115#
116dirchk : # no pathname match
117 acbl $buf+BLKSIZ-1,$DIRSIZ,r7,nxtent # loop if
118# more dir entries in this buffer
119 brb get1b # get another dir block into buffer
120#
121# here if inode for desired file has been read in
122getfil :
123 clrl bufptr # new buffer ptr is low core
124getlop :
125 bsbb rmblk # get a block in the file
126 beql clear # branch if no more file blocks to read
127# skip above branch if more file blocks to read in
128 addl2 $BLKSIZ,bufptr # next page in low core
129 brb getlop # go get next block of input file
130#
131# clear core
132#
133clear :
134 movl *$size,r3
135clrcor :
136 clrq (r3)
137 acbl $RELOC,$8,r3,clrcor
138#
139# go execute file
140#
141 calls $0,*$0
142 brw start2
143#
144#
145# subroutine to get the inode whose no. is in r0
146#
147iget :
148 addl3 $(INOBLK*(NBOO+NSUP))-1,r0,r8 # have to add in 2 blocks (boot and super)
149# worth of dummy inodes to calculate proper inode block
150 divl3 $INOBLK,r8,r4 # calculate inode block , put in r4
151 bsbw rblk # read in block containing desired inode
152 bicl2 $INOMSK,r8
153 mull2 $INOSIZ,r8 # x inode size = offset in block
154 addl2 $buf,r8 # buffer loc of inode entry
155# move inode entry to separate buffer
156 movc3 $time-inode,(r8),*$inode
157 rsb
158#
159# subr to read in 1 of blocks (bno) in 'addr[]'
160#
161rmblk :
162 movzwl *$bno,r0
163 addw2 $3,*$bno # index into 'addr[]' array in inode entry
164 addl2 $addr,r0
165# this boot assumes only small files(<11 blocks)
166 extzv $0,$24,(r0),r4 # get low 2 bytes of block no. -> r4
167 bneq rblk # read in block if non-zero
168# zero cc is set on return
169 rsb
170#
171# subr to read disc block no. specified in r4 from RP06, drive 0
172#
173rblk :
174 mull2 $BLKSIZ/512,r4
175 clrl r5
176 ediv *$rpst,r4,*$RP_cyl,r1
177# (r4 = block no.)/(no. blocks per cyl) -> cyl no.
178# r1 = remainder = block offset with in cylinder
179 clrl r2
180 ediv *$rpsec,r1,r1,r0
181# r1 = track no. ; ; sector no. in low part RP_stk
182 insv r1,$8,$5,r0 # move track no. into RP_stk
183 movl r0,*$RP_stk # track-sector
184 movl $-BLKSIZ,*$M_bc # byte count
185 ashl $-9,bufptr,r0 # start page no. of buffer
186 bisl3 $0x80000000,r0,*$M_map # MBA map reg =
187# valid bit + phys page no.
188 incl r0
189 bisl3 $0x80000000,r0,*$(M_map+4)
190 clrl *$M_var # buffer has been 512-byte aligned + map reg 0
191 movl $RP_RED+RP_GO,*$RP_cr # disc read function code
192rprdy :
193 movl *$RP_sr,r0
194 bbc $RP_pDRY,r0,rprdy # loop unitl ready
195 bbs $RP_pERR,r0,rperr # branch if error
196 bicpsw $2 # set zero cc for caller success
197 rsb # normal return
198 rperr : # disc i/o error
199 halt # halt on error
200#
201#
202bufptr : .long buf
203names :
204 .byte 'b,'o,'o,'t,0,0,0,0,0,0,0,0,0,0
205 .byte 0
206#
207end:
208#
209 .set buf,RELOC-1536
210 .set inode,RELOC-512
211 .set mode,inode
212 .set nlink,mode+2
213 .set uid,nlink+2
214 .set gid,uid+2
215 .set size,gid+2
216 .set addr,size+4
217 .set time,addr+40
218 .set bno,time+12
219 .set rptrk,bno+4
220 .set rpsec,rptrk+4
221 .set rpst,rpsec+4