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