Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: ra.c,v 1.23 2025/07/14 12:39:34 hans 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
     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
    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
    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 
    311 int
    312 raclose(struct open_file *f)
    313 {
    314 	/* Reset controller by starting a soft initialization */
    315 	*ra_ip = 0;
    316 
    317 	return 0;
    318 }
    319