xref: /netbsd/sys/arch/alpha/alpha/dec_3000_500.c (revision bf9ec67e)
1 /* $NetBSD: dec_3000_500.c,v 1.33 2001/04/25 17:53:04 bouyer Exp $ */
2 
3 /*
4  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
5  * All rights reserved.
6  *
7  * Author: Chris G. Demetriou
8  *
9  * Permission to use, copy, modify and distribute this software and
10  * its documentation is hereby granted, provided that both the copyright
11  * notice and this permission notice appear in all copies of the
12  * software, derivative works or modified versions, and any portions
13  * thereof, and that both notices appear in supporting documentation.
14  *
15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18  *
19  * Carnegie Mellon requests users of this software to return to
20  *
21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22  *  School of Computer Science
23  *  Carnegie Mellon University
24  *  Pittsburgh PA 15213-3890
25  *
26  * any improvements or extensions that they make and grant Carnegie the
27  * rights to redistribute these changes.
28  */
29 /*
30  * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
31  */
32 
33 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
34 
35 __KERNEL_RCSID(0, "$NetBSD: dec_3000_500.c,v 1.33 2001/04/25 17:53:04 bouyer Exp $");
36 
37 #include "opt_new_scc_driver.h"
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/device.h>
42 #include <sys/termios.h>
43 #include <dev/cons.h>
44 
45 #include <machine/rpb.h>
46 #include <machine/autoconf.h>
47 #include <machine/conf.h>
48 
49 #include <dev/tc/tcvar.h>
50 #include <dev/tc/tcdsvar.h>
51 #include <alpha/tc/tc_3000_500.h>
52 #ifndef NEW_SCC_DRIVER
53 #include <alpha/tc/sccvar.h>
54 #endif
55 
56 #include <machine/z8530var.h>
57 #include <dev/tc/zs_ioasicvar.h>
58 
59 #include <dev/scsipi/scsi_all.h>
60 #include <dev/scsipi/scsipi_all.h>
61 #include <dev/scsipi/scsiconf.h>
62 
63 #include "wsdisplay.h"
64 
65 void dec_3000_500_init __P((void));
66 static void dec_3000_500_cons_init __P((void));
67 static void dec_3000_500_device_register __P((struct device *, void *));
68 
69 static const char dec_3000_500_sp[] = "DEC 3000/400 (\"Sandpiper\")";
70 static const char dec_3000_500_sf[] = "DEC 3000/500 (\"Flamingo\")";
71 
72 const struct alpha_variation_table dec_3000_500_variations[] = {
73 	{ SV_ST_SANDPIPER, dec_3000_500_sp },
74 	{ SV_ST_FLAMINGO, dec_3000_500_sf },
75 	{ SV_ST_HOTPINK, "DEC 3000/500X (\"Hot Pink\")" },
76 	{ SV_ST_FLAMINGOPLUS, "DEC 3000/800 (\"Flamingo+\")" },
77 	{ SV_ST_SANDPLUS, "DEC 3000/600 (\"Sandpiper+\")" },
78 	{ SV_ST_SANDPIPER45, "DEC 3000/700 (\"Sandpiper45\")" },
79 	{ SV_ST_FLAMINGO45, "DEC 3000/900 (\"Flamingo45\")" },
80 	{ 0, NULL },
81 };
82 
83 void
84 dec_3000_500_init()
85 {
86 	u_int64_t variation;
87 
88 	platform.family = "DEC 3000/500 (\"Flamingo\")";
89 
90 	if ((platform.model = alpha_dsr_sysname()) == NULL) {
91 		variation = hwrpb->rpb_variation & SV_ST_MASK;
92 		if (variation == SV_ST_ULTRA) {
93 			/* These are really the same. */
94 			variation = SV_ST_FLAMINGOPLUS;
95 		}
96 		if ((platform.model = alpha_variation_name(variation,
97 		    dec_3000_500_variations)) == NULL) {
98 			/*
99 			 * This is how things used to be done.
100 			 */
101 			if (variation == SV_ST_RESERVED) {
102 				if (hwrpb->rpb_variation & SV_GRAPHICS)
103 					platform.model = dec_3000_500_sf;
104 				else
105 					platform.model = dec_3000_500_sp;
106 			} else
107 				platform.model = alpha_unknown_sysname();
108 		}
109 	}
110 
111 	platform.iobus = "tcasic";
112 	platform.cons_init = dec_3000_500_cons_init;
113 	platform.device_register = dec_3000_500_device_register;
114 }
115 
116 static void
117 dec_3000_500_cons_init()
118 {
119 	struct ctb *ctb;
120 
121 	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
122 
123 #ifndef NEW_SCC_DRIVER
124 	switch (ctb->ctb_term_type) {
125 	case CTB_GRAPHICS:
126 		alpha_donot_kludge_scc = 1;
127 		return;
128 	case CTB_PRINTERPORT:
129 		return;
130 	default:
131 		goto badconsole;
132 	}
133 #else
134 
135 	switch (ctb->ctb_term_type) {
136 	case CTB_GRAPHICS:
137 #if NWSDISPLAY > 0
138 		/* display console ... */
139 		if (zs_ioasic_lk201_cnattach(0x1e0000000, 0x00180000, 0) == 0 &&
140 		    tc_3000_500_fb_cnattach(
141 		     CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot)) == 0) {
142 			break;
143 		}
144 #endif
145 		printf("consinit: Unable to init console on keyboard and ");
146 		printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot);
147 		printf("Using serial console.\n");
148 		/* FALLTHROUGH */
149 
150 	case CTB_PRINTERPORT:
151 		/* serial console ... */
152 		/*
153 		 * XXX This could stand some cleanup...
154 		 */
155 		{
156 			/*
157 			 * Delay to allow PROM putchars to complete.
158 			 * FIFO depth * character time,
159 			 * character time = (1000000 / (defaultrate / 10))
160 			 */
161 			DELAY(160000000 / 9600);	/* XXX */
162 
163 			/*
164 			 * Console is channel B of the second SCC.
165 			 * XXX Should use ctb_line_off to get the
166 			 * XXX line parameters--these are the defaults.
167 			 */
168 			zs_ioasic_cnattach(0x1e0000000, 0x00180000, 1);
169 			break;
170 		}
171 
172 	default:
173 		goto badconsole;
174 	}
175 #endif
176 	return;
177 badconsole:
178 	printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
179 	printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
180 
181 	panic("consinit: unknown console type %lu\n",
182 	    ctb->ctb_term_type);
183 }
184 
185 static void
186 dec_3000_500_device_register(dev, aux)
187 	struct device *dev;
188 	void *aux;
189 {
190 	static int found, initted, scsiboot, netboot;
191 	static struct device *scsidev;
192 	static struct device *tcdsdev;
193 	struct bootdev_data *b = bootdev_data;
194 	struct device *parent = dev->dv_parent;
195 	struct cfdata *cf = dev->dv_cfdata;
196 	struct cfdriver *cd = cf->cf_driver;
197 
198 	if (found)
199 		return;
200 
201 	if (!initted) {
202 		scsiboot = (strcmp(b->protocol, "SCSI") == 0);
203 		netboot = (strcmp(b->protocol, "BOOTP") == 0) ||
204 		    (strcmp(b->protocol, "MOP") == 0);
205 #if 0
206 		printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
207 #endif
208 		initted = 1;
209 	}
210 
211 	/*
212 	 * for scsi boot, we look for "tcds", make sure it has the
213 	 * right slot number, then find the "asc" on this tcds that
214 	 * as the right channel.  then we find the actual scsi
215 	 * device we came from.  note: no SCSI LUN support (yet).
216 	 */
217 	if (scsiboot && (strcmp(cd->cd_name, "tcds") == 0)) {
218 		struct tc_attach_args *tcargs = aux;
219 
220 		if (b->slot != tcargs->ta_slot)
221 			return;
222 
223 		tcdsdev = dev;
224 #if 0
225 		printf("\ntcdsdev = %s\n", dev->dv_xname);
226 #endif
227 	}
228 	if (scsiboot && tcdsdev &&
229 	    (strcmp(cd->cd_name, "asc") == 0)) {
230 		struct tcdsdev_attach_args *ta = aux;
231 
232 		if (parent != (struct device *)tcdsdev)
233 			return;
234 
235 		if (ta->tcdsda_chip != b->channel)
236 			return;
237 
238 		scsidev = dev;
239 #if 0
240 		printf("\nscsidev = %s\n", dev->dv_xname);
241 #endif
242 	}
243 
244 	if (scsiboot && scsidev &&
245 	    (strcmp(cd->cd_name, "sd") == 0 ||
246 	     strcmp(cd->cd_name, "st") == 0 ||
247 	     strcmp(cd->cd_name, "cd") == 0)) {
248 		struct scsipibus_attach_args *sa = aux;
249 
250 		if (parent->dv_parent != scsidev)
251 			return;
252 
253 		if (b->unit / 100 != sa->sa_periph->periph_target)
254 			return;
255 
256 		/* XXX LUN! */
257 
258 		switch (b->boot_dev_type) {
259 		case 0:
260 			if (strcmp(cd->cd_name, "sd") &&
261 			    strcmp(cd->cd_name, "cd"))
262 				return;
263 			break;
264 		case 1:
265 			if (strcmp(cd->cd_name, "st"))
266 				return;
267 			break;
268 		default:
269 			return;
270 		}
271 
272 		/* we've found it! */
273 		booted_device = dev;
274 #if 0
275 		printf("\nbooted_device = %s\n", booted_device->dv_xname);
276 #endif
277 		found = 1;
278 	}
279 
280 	if (netboot) {
281                 if (b->slot == 7 && strcmp(cd->cd_name, "le") == 0 &&
282 		    strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic")
283 		     == 0) {
284 			/*
285 			 * no need to check ioasic_attach_args, since only
286 			 * one le on ioasic.
287 			 */
288 
289 			booted_device = dev;
290 #if 0
291 			printf("\nbooted_device = %s\n", booted_device->dv_xname);
292 #endif
293 			found = 1;
294 			return;
295 		}
296 
297 		/*
298 		 * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS
299 		 */
300         }
301 }
302