xref: /original-bsd/sys/vax/mdec/rlboot.c (revision 037861c2)
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