1 /* rlboot.c 4.1 83/02/16 */ 2 3 /* 4 * RL02 disk boot program to load "/boot" from 5 * a UNIX filesystem (starting at block 1 on pack on 6 * drive 0) into low core and to execute that file. 7 * 8 * This program can only read regular small 1k byte (3bsd+) files 9 * from the root of a UNIX filesystem. 10 * 11 * Hacked from a rk07 boot by Hank Trapnell, IMS. 12 * 13 * /sys/mdec/hlboot.s 4.1 82/12/17 14 */ 15 .set BLKSIZ,1024 /* file system block size */ 16 .set BPSECT,256 /* size of sector in bytes */ 17 .set RELOC,0x50000 18 .set INOSIZ,64 /* no. bytes/inode entry */ 19 .set INOBLK,BLKSIZ/INOSIZ /* no. inodes/disc block */ 20 .set INOMSK,0xfffffff0 /* changes with inode size */ 21 .set NAMSIZ,14 /* bytes in directory name */ 22 .set ENTADR,024 /* offset to entry addr in a.out */ 23 .set DIRSIZ,16 /* size of directory entry, bytes */ 24 .set ROOTINO,2 /* root dir inode no. */ 25 .set NBOO,1 /* no. of boot blocks */ 26 .set NSUP,1 /* no. of superblocks */ 27 .set SID,62 /* system ID register */ 28 /* UBA registers */ 29 .set UBA_CNFGR,0 /* UBA configuration register */ 30 .set UBA_CR,4 /* UBA control register offset */ 31 .set UBA_MAP,0x800 /* UBA offset to map reg's */ 32 .set UBAinit,1 /* UBA init bit in UBA control reg */ 33 .set pUBIC,16 /* Unibus init complete */ 34 /* RL11 registers and bits */ 35 .set HL,0174400-0160000 /* address of RL11 */ 36 .set HL_cs,HL+0 /* control and status */ 37 .set HL_ba,HL+2 /* bus address */ 38 .set HL_da,HL+4 /* disk address */ 39 .set HL_mp,HL+6 /* word count */ 40 .set HLSECT,40 /* sectors per track */ 41 .set HLTRAC,2 /* tracks per cylinder */ 42 .set HLST,HLSECT*HLTRAC 43 .set HL_GO,0 /* go bit */ 44 .set HL_RCOM,014 /* read command */ 45 .set HL_SEEK,06 /* seek */ 46 .set HL_GSTAT,04 /* get status command */ 47 .set HL_RHDR,010 /* read header */ 48 .set HL_RESET,013 /* reset drive */ 49 .set HL_HS,020 /* head select */ 50 .set HL_DIR,04 /* seek direction */ 51 .set HL_pRDY,7 /* position of ready bit */ 52 .set HL_pERR,15 /* position of error bit */ 53 54 init: 55 /* r9 UBA address */ 56 /* r10 umem addr */ 57 .word 0 /* entry mask for dec monitor */ 58 nop;nop;nop;nop;nop;nop;nop;nop /* some no-ops for 750 boot to skip */ 59 nop;nop; 60 /* get cpu type and find the first uba */ 61 mfpr $SID,r0 62 extzv $24,$8,r0,r0 /* get cpu type */ 63 ashl $2,r0,r1 64 movab physUBA,r2 /* get physUBA[cpu] */ 65 addl2 r1,r2 66 movl (r2),r9 67 movab physUMEM,r2 /* get physUMEM[cpu] */ 68 addl2 r1,r2 69 movl (r2),r10 70 /* if 780, init uba */ 71 cmpl r0,$1 72 bneq 2f 73 movl $UBAinit,UBA_CR(r9) 74 1: 75 bbc $pUBIC,UBA_CNFGR(r9),1b 76 2: 77 /* init rl11, and drive 0, don't check for any errors now */ 78 movw $HL_RESET,HL_da(r10) 79 movw $HL_GSTAT+HL_GO,HL_cs(r10) 80 81 /* relocate to high core */ 82 start: 83 movl r5,r11 /* boot flags */ 84 movl $RELOC,sp 85 moval init,r6 86 movc3 $end,(r6),(sp) 87 jmp *$RELOC+start2 88 /* now running relocated */ 89 /* search for ``boot'' in root inode */ 90 start2: 91 movl $names+RELOC,r6 92 movzbl $ROOTINO,r0 93 nxti: 94 clrw *$bno /* start with first block in inode */ 95 bsbw iget 96 tstb (r6) 97 beql getfil /* found correct inode! */ 98 get1b: 99 bsbw rmblk /* read inode from block now in memory */ 100 beql start2 101 movl $buf,r7 102 nxtent: 103 tstw (r7) 104 beql dirchk 105 cmpc3 $NAMSIZ,(r6),2(r7) 106 bneq dirchk 107 movzwl (r7),r0 108 addl2 $NAMSIZ,r6 109 brb nxti 110 dirchk: 111 acbl $buf+BLKSIZ-1,$DIRSIZ,r7,nxtent 112 brb get1b 113 /* found inode for desired file... read it in */ 114 getfil: 115 clrl bufptr 116 getlop: 117 bsbb rmblk 118 beql clear 119 addl2 $BLKSIZ,bufptr 120 brb getlop 121 clear: 122 movl *$size,r3 123 clrcor: 124 clrq (r3) 125 acbl $RELOC,$8,r3,clrcor 126 /* run loaded program */ 127 movl $8,r10 /* major("/dev/hl0a") */ 128 calls $0,*$0 129 brw start2 130 /* iget: get inode block whose # is in r0 */ 131 iget: 132 addl3 $(INOBLK*(NBOO+NSUP))-1,r0,r8 133 divl3 $INOBLK,r8,r4 134 bsbw rblk 135 bicl2 $INOMSK,r8 136 mull2 $INOSIZ,r8 137 addl2 $buf,r8 138 movc3 $time-inode,(r8),*$inode 139 rsb 140 /* rmblk: read in bno into addr */ 141 rmblk: 142 movzwl *$bno,r0 143 addw2 $3,*$bno 144 addl2 $addr,r0 145 /* this boot assumes only small files (<=10k bytes, ie. no indirect blocks) */ 146 extzv $0,$24,(r0),r4 147 bneq rblk 148 rsb 149 /* rblk: read disk block whose number is in r4 */ 150 rblk: 151 movzbw $HL_RHDR+HL_GO,HL_cs(r10) 152 bsbw hlwait 153 movzwl HL_mp(r10),r0 154 extzv $7,$9,r0,r3 /* get current cylinder */ 155 mull2 $BLKSIZ/BPSECT,r4 156 clrl r5 157 ediv $HLST,r4,r0,r1 /* get desired cylinder */ 158 movzbl $1,r5 159 subl2 r0,r3 160 bgeq 1f 161 mnegl r3,r3 162 bisl2 $HL_DIR,r5 /* move towards the spindle */ 163 1: 164 insv r3,$7,$9,r5 165 clrl r2 166 ediv $HLSECT,r1,r2,r1 167 tstl r2 168 beql 1f 169 bisl2 $HL_HS,r5 170 1: 171 movl r5,HL_da(r10) 172 ashl $7,r0,r5 173 movw $HL_SEEK+HL_GO,HL_cs(r10) 174 bsbb hlwait 175 tstl r2 176 beql 1f 177 bisl2 $0x40,r5 178 1: 179 addl2 r1,r5 180 ashl $-9,bufptr,r0 181 bisl3 $0x80000000,r0,UBA_MAP(r9) 182 incl r0 183 bisl3 $0x80000000,r0,UBA_MAP+4(r9) 184 clrw HL_ba(r10) 185 movw r5,HL_da(r10) 186 movw $-BLKSIZ/2,HL_mp(r10) 187 movw $HL_RCOM+HL_GO,HL_cs(r10) 188 hlwait: /* wait for controller ready */ 189 movw HL_cs(r10),r0 190 bbc $HL_pRDY,r0,hlwait 191 bbs $HL_pERR,r0,hlerr 192 bicpsw $2 193 rsb 194 hlerr: 195 halt /* ungraceful */ 196 bufptr: .long buf 197 names: .byte 'b,'o,'o,'t,0,0,0,0,0,0,0,0,0,0 198 .byte 0 199 physUBA: 200 .long 0 201 .long 0x20006000 /* 11/780 */ 202 .long 0xf30000 /* 11/750 */ 203 .long 0xf26000 /* 11/7ZZ */ 204 physUMEM: 205 .long 0 206 .long 0x2013e000 /* 11/780 */ 207 .long 0xffe000 /* 11/750 */ 208 .long 0xffe000 /* 11/7ZZ */ 209 end: 210 .set buf,RELOC-1536 211 .set inode,RELOC-512 212 .set mode,inode 213 .set nlink,mode+2 214 .set uid,nlink+2 215 .set gid,uid+2 216 .set size,gid+2 217 .set addr,size+4 218 .set time,addr+40 219 .set bno,time+12 220