xref: /netbsd-src/sys/arch/vax/boot/boot/ra.c (revision 2af6320d24b08bad927f1dab5aab9b48d9538d47)
1 /*	$NetBSD: ra.c,v 1.22 2018/03/21 18:27:27 ragge Exp $ */
2 /*
3  * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27  /* All bugs are subject to removal without further notice */
28 
29 #define NRSP 1 /* Kludge */
30 #define NCMD 1 /* Kludge */
31 
32 #include <sys/param.h>
33 #include <sys/disklabel.h>
34 
35 #include <lib/libsa/stand.h>
36 
37 #include <lib/libkern/libkern.h>
38 
39 #include "../include/pte.h"
40 #include "../include/rpb.h"
41 
42 #include <dev/mscp/mscp.h>
43 #include <dev/mscp/mscpreg.h>
44 
45 #include <dev/bi/bireg.h>
46 #include <dev/bi/kdbreg.h>
47 
48 #include "vaxstand.h"
49 
50 static void command(int, int);
51 
52 /*
53  * These routines for RA disk standalone boot is wery simple,
54  * assuming a lots of thing like that we only working at one ra disk
55  * a time, no separate routines for uba driver etc..
56  * This code is foolish and should need a cleanup.
57  * But it works :)
58  */
59 
60 static volatile struct uda {
61 	struct	mscp_1ca uda_ca;  /* communications area */
62 	struct	mscp uda_rsp;	  /* response packets */
63 	struct	mscp uda_cmd;	  /* command packets */
64 } uda;
65 
66 static struct disklabel ralabel;
67 static char io_buf[DEV_BSIZE];
68 static int dpart, dunit, is_tmscp, curblock;
69 static volatile u_short *ra_ip, *ra_sa, *ra_sw;
70 
71 int
raopen(struct open_file * f,int adapt,int ctlr,int unit,int part)72 raopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
73 {
74 	static volatile struct uda *ubauda;
75 	unsigned short johan, johan2;
76 	size_t i;
77 	int err;
78 	char *msg;
79 
80 #ifdef DEV_DEBUG
81 	printf("raopen: adapter %d ctlr %d unit %d part %d\n",
82 	    adapt, ctlr, unit, part);
83 	printf("raopen: csrbase %x nexaddr %x\n", csrbase, nexaddr);
84 #endif
85 	memset(&ralabel, 0, sizeof(struct disklabel));
86 	memset((void *)&uda, 0, sizeof(struct uda));
87 	if (bootrpb.devtyp == BDEV_TK)
88 		is_tmscp = 1;
89 	dunit = unit;
90 	dpart = part;
91 	if (ctlr < 0)
92 		ctlr = 0;
93 	curblock = 0;
94 	if (csrbase) { /* On a uda-alike adapter */
95 		if (askname == 0) {
96 			csrbase = bootrpb.csrphy;
97 			dunit = bootrpb.unit;
98 			nexaddr = bootrpb.adpphy;
99 		} else
100 			csrbase += (ctlr ? 000334 : 012150);
101 		ra_ip = (u_short *)csrbase;
102 		ra_sa = ra_sw = (u_short *)csrbase + 1;
103 
104 		ubauda = (struct uda *)ubmap(494,
105 		    (int)&uda, sizeof(struct uda));
106 		johan = (((u_int)ubauda) & 0xffff) + 8;
107 		johan2 = (((u_int)ubauda) >> 16) & 077;
108 		*ra_ip = 0; /* Start init */
109 		bootrpb.csrphy = csrbase;
110 	} else {
111 		paddr_t kdaddr;
112 		volatile int *w;
113 		volatile int i = 10000;
114 
115 		if (askname == 0) {
116 			nexaddr = bootrpb.csrphy;
117 			dunit = bootrpb.unit;
118 		} else {
119 			nexaddr = (bootrpb.csrphy & ~(BI_NODESIZE - 1)) + KDB_IP;
120 			bootrpb.csrphy = nexaddr;
121 		}
122 
123 		kdaddr = nexaddr & ~(BI_NODESIZE - 1);
124 		ra_ip = (u_short *)(kdaddr + KDB_IP);
125 		ra_sa = (u_short *)(kdaddr + KDB_SA);
126 		ra_sw = (u_short *)(kdaddr + KDB_SW);
127 		johan = ((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff;
128 		johan2 = (((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff0000) >> 16;
129 		w = (int *)(kdaddr + BIREG_VAXBICSR);
130 		*w = *w | BICSR_NRST;
131 		while (i--) /* Need delay??? */
132 			;
133 		w = (int *)(kdaddr + BIREG_BER);
134 		*w = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);/* ??? */
135 		ubauda = &uda;
136 	}
137 
138 #ifdef DEV_DEBUG
139 	printf("start init\n");
140 #endif
141 	/* Init of this uda */
142 	while ((*ra_sa & MP_STEP1) == 0)
143 		;
144 #ifdef DEV_DEBUG
145 	printf("MP_STEP1...");
146 #endif
147 	*ra_sw = 0x8000;
148 	while ((*ra_sa & MP_STEP2) == 0)
149 		;
150 #ifdef DEV_DEBUG
151 	printf("MP_STEP2...");
152 #endif
153 
154 	*ra_sw = johan;
155 	while ((*ra_sa & MP_STEP3) == 0)
156 		;
157 #ifdef DEV_DEBUG
158 	printf("MP_STEP3...");
159 #endif
160 
161 	*ra_sw = johan2;
162 	while ((*ra_sa & MP_STEP4) == 0)
163 		;
164 #ifdef DEV_DEBUG
165 	printf("MP_STEP4\n");
166 #endif
167 
168 	*ra_sw = 0x0001;
169 	uda.uda_ca.ca_rspdsc = (int)&ubauda->uda_rsp.mscp_cmdref;
170 	uda.uda_ca.ca_cmddsc = (int)&ubauda->uda_cmd.mscp_cmdref;
171 	if (is_tmscp) {
172 		uda.uda_cmd.mscp_un.un_seq.seq_addr =
173 		    (long *)&uda.uda_ca.ca_cmddsc;
174 		uda.uda_rsp.mscp_un.un_seq.seq_addr =
175 		    (long *)&uda.uda_ca.ca_rspdsc;
176 		uda.uda_cmd.mscp_vcid = 1;
177 		uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
178 	}
179 
180 	command(M_OP_SETCTLRC, 0);
181 	uda.uda_cmd.mscp_unit = dunit;
182 	command(M_OP_ONLINE, 0);
183 
184 	if (is_tmscp) {
185 		if (part) {
186 #ifdef DEV_DEBUG
187 			printf("Repos of tape...");
188 #endif
189 			uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
190 			command(M_OP_POS, 0);
191 			uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
192 #ifdef DEV_DEBUG
193 			printf("Done!\n");
194 #endif
195 		}
196 		return 0;
197 	}
198 #ifdef DEV_DEBUG
199 	printf("reading disklabel\n");
200 #endif
201 	err = rastrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
202 	if(err){
203 		printf("reading disklabel: %s\n",strerror(err));
204 		return 0;
205 	}
206 
207 #ifdef DEV_DEBUG
208 	printf("getting disklabel\n");
209 #endif
210 	msg = getdisklabel(io_buf+LABELOFFSET, &ralabel);
211 	if (msg)
212 		printf("getdisklabel: %s\n", msg);
213 	return(0);
214 }
215 
216 static void
command(int cmd,int arg)217 command(int cmd, int arg)
218 {
219 	volatile short hej;
220 	int to;
221 
222 igen:	uda.uda_cmd.mscp_opcode = cmd;
223 	uda.uda_cmd.mscp_modifier = arg;
224 
225 	uda.uda_cmd.mscp_msglen = MSCP_MSGLEN;
226 	uda.uda_rsp.mscp_msglen = MSCP_MSGLEN;
227 	uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
228 	uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
229 #ifdef DEV_DEBUG
230 	printf("sending cmd %x...", cmd);
231 #endif
232 	hej = *ra_ip;
233 	__USE(hej);
234 	to = 10000000;
235 	while (uda.uda_ca.ca_rspdsc < 0) {
236 //		if (uda.uda_ca.ca_cmdint)
237 //			uda.uda_ca.ca_cmdint = 0;
238 		if (--to < 0) {
239 #ifdef DEV_DEBUG
240 			printf("timing out, retry\n");
241 #endif
242 			goto igen;
243 		}
244 	}
245 #ifdef DEV_DEBUG
246 	printf("sent.\n");
247 #endif
248 }
249 
250 int
rastrategy(void * f,int func,daddr_t dblk,size_t size,void * buf,size_t * rsize)251 rastrategy(void *f, int func, daddr_t dblk,
252     size_t size, void *buf, size_t *rsize)
253 {
254 
255 #ifdef DEV_DEBUG
256 	printf("rastrategy: buf %p is_tmscp %d\n",
257 	    buf, is_tmscp);
258 #endif
259 
260 	uda.uda_cmd.mscp_seq.seq_buffer = ubmap(0, (int)buf, size);
261 
262 	if (is_tmscp) {
263 		int i;
264 
265 		/*
266 		 * First position tape. Remember where we are.
267 		 */
268 		if (dblk < curblock) {
269 			uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
270 			command(M_OP_POS, 12); /* 12 == step block backward */
271 		} else {
272 			uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
273 			command(M_OP_POS, 4); /* 4 == step block forward */
274 		}
275 		curblock = size/512 + dblk;
276 
277 		/*
278 		 * Read in the number of blocks we need.
279 		 * Why doesn't read of multiple blocks work?????
280 		 */
281 		for (i = 0 ; i < size/512 ; i++) {
282 			uda.uda_cmd.mscp_seq.seq_lbn = 1;
283 			uda.uda_cmd.mscp_seq.seq_bytecount = 512;
284 			uda.uda_cmd.mscp_seq.seq_buffer =
285 			    (((u_int)buf) & 0x1ff) + i * 512;
286 			uda.uda_cmd.mscp_unit = dunit;
287 			command(M_OP_READ, 0);
288 		}
289 	} else {
290 
291 		uda.uda_cmd.mscp_seq.seq_lbn =
292 		    dblk + ralabel.d_partitions[dpart].p_offset;
293 		uda.uda_cmd.mscp_seq.seq_bytecount = size;
294 		uda.uda_cmd.mscp_unit = dunit;
295 #ifdef DEV_DEBUG
296 		printf("rastrategy: blk 0x%lx count %lx unit %x\n",
297 		    uda.uda_cmd.mscp_seq.seq_lbn, size, dunit);
298 #endif
299 #ifdef notdef
300 		if (func == F_WRITE)
301 			command(M_OP_WRITE, 0);
302 		else
303 #endif
304 			command(M_OP_READ, 0);
305 	}
306 
307 	*rsize = size;
308 	return 0;
309 }
310