xref: /netbsd/sys/arch/vax/boot/boot/ctu.c (revision 2d5d8524)
1 /*	$NetBSD: ctu.c,v 1.9 2017/05/22 16:59:32 ragge Exp $ */
2 /*
3  * Copyright (c) 1996 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 /*
28  * Standalone device driver for 11/750 Console TU58.
29  * It can only handle reads, and doesn't calculate checksum.
30  */
31 
32 #include <sys/param.h>
33 
34 #include <lib/libsa/stand.h>
35 
36 #include <machine/mtpr.h>
37 #include <machine/rsp.h>
38 
39 #include "vaxstand.h"
40 
41 static short ctu_cksum(unsigned short *, int);
42 
43 enum tu_state {
44 	SC_INIT,
45 	SC_READY,
46 	SC_SEND_CMD,
47 	SC_GET_RESP,
48 };
49 
50 volatile struct tu_softc {
51 	enum	tu_state sc_state;
52 	char	sc_rsp[15];	/* Should be struct rsb; but don't work */
53 	u_char	*sc_xfptr;	/* Current char to xfer */
54 	int	sc_nbytes;	/* Number of bytes to xfer */
55 	int	sc_xbytes;	/* Number of xfer'd bytes */
56 	int	sc_bbytes;	/* Number of xfer'd bytes this block */
57 } tu_sc;
58 
59 void	ctutintr(void);
60 void	cturintr(void);
61 
62 int
ctuopen(struct open_file * f,int adapt,int ctlr,int unit,int part)63 ctuopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
64 {
65 
66 	tu_sc.sc_state = SC_INIT;
67 
68 	mtpr(RSP_TYP_INIT, PR_CSTD);
69 	cturintr();
70 	tu_sc.sc_state = SC_READY;
71 	return 0;
72 
73 }
74 
75 int
ctustrategy(void * f,int func,daddr_t dblk,size_t size,void * buf,size_t * rsize)76 ctustrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize)
77 {
78 	struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp;
79 
80 	tu_sc.sc_xfptr = buf;
81 	tu_sc.sc_nbytes = size;
82 	tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0;
83 
84 	rsp->rsp_typ = RSP_TYP_COMMAND;
85 	rsp->rsp_sz = 012;
86 	rsp->rsp_op = RSP_OP_READ;
87 	rsp->rsp_mod = 0;
88 	rsp->rsp_drv = 0;
89 	rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0;
90 	rsp->rsp_cnt = tu_sc.sc_nbytes;
91 	rsp->rsp_blk = dblk;
92 	rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6);
93 	tu_sc.sc_state = SC_SEND_CMD;
94 	while (tu_sc.sc_state != SC_GET_RESP)
95 		ctutintr();
96 	while (tu_sc.sc_state != SC_READY)
97 		cturintr();
98 	*rsize = size;
99 	return 0;
100 }
101 
102 void
cturintr(void)103 cturintr(void)
104 {
105 	int	status;
106 
107 	while ((mfpr(PR_CSRS) & 0x80) == 0)
108 		;
109 
110 	status = mfpr(PR_CSRD);
111 
112 	switch (tu_sc.sc_state) {
113 
114 	case SC_INIT:
115 		break;
116 
117 	case SC_GET_RESP:
118 		if (tu_sc.sc_xbytes == tu_sc.sc_nbytes) {
119 			tu_sc.sc_bbytes++;
120 			if (tu_sc.sc_bbytes == 146)
121 				tu_sc.sc_state = SC_READY;
122 			break;
123 		}
124 		tu_sc.sc_bbytes++;
125 		if (tu_sc.sc_bbytes <  3) /* Data header */
126 			break;
127 		if (tu_sc.sc_bbytes == 132) { /* Finished */
128 			tu_sc.sc_bbytes = 0;
129 			break;
130 		}
131 		if (tu_sc.sc_bbytes == 131) /* First checksum */
132 			break;
133 		tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status;
134 		break;
135 
136 	case SC_READY:
137 	case SC_SEND_CMD:
138 		break;
139 	}
140 
141 }
142 
143 void
ctutintr(void)144 ctutintr(void)
145 {
146 	int	c;
147 
148 	while ((mfpr(PR_CSTS) & 0x80) == 0)
149 		;
150 
151 	c = tu_sc.sc_rsp[tu_sc.sc_xbytes++] & 0xff;
152 	mtpr(c, PR_CSTD);
153 	if (tu_sc.sc_xbytes > 13) {
154 		tu_sc.sc_state = SC_GET_RESP;
155 		tu_sc.sc_xbytes = 0;
156 	}
157 }
158 
159 short
ctu_cksum(unsigned short * buf,int words)160 ctu_cksum(unsigned short *buf, int words)
161 {
162 	int i, cksum;
163 
164 	for (i = cksum = 0; i < words; i++)
165 		cksum += buf[i];
166 
167 hej:	if (cksum > 65535) {
168 		cksum = (cksum & 65535) + (cksum >> 16);
169 		goto hej;
170 	}
171 	return cksum;
172 }
173