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