xref: /netbsd/sys/arch/alpha/alpha/dec_1000a.c (revision c4a72b64)
1 /* $NetBSD: dec_1000a.c,v 1.18 2002/09/27 15:35:33 provos Exp $ */
2 
3 /*
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is based on dec_kn20aa.c, written by Chris G. Demetriou at
8  * Carnegie-Mellon University. Platform support for Noritake, Pintake, and
9  * Corelle by Ross Harvey with copyright assignment by permission of Avalon
10  * Computer Systems, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the NetBSD
23  *	Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
43  * All rights reserved.
44  *
45  * Author: Chris G. Demetriou
46  *
47  * Permission to use, copy, modify and distribute this software and
48  * its documentation is hereby granted, provided that both the copyright
49  * notice and this permission notice appear in all copies of the
50  * software, derivative works or modified versions, and any portions
51  * thereof, and that both notices appear in supporting documentation.
52  *
53  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
54  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
55  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
56  *
57  * Carnegie Mellon requests users of this software to return to
58  *
59  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
60  *  School of Computer Science
61  *  Carnegie Mellon University
62  *  Pittsburgh PA 15213-3890
63  *
64  * any improvements or extensions that they make and grant Carnegie the
65  * rights to redistribute these changes.
66  */
67 /*
68  * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
69  */
70 
71 #include "opt_kgdb.h"
72 
73 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
74 
75 __KERNEL_RCSID(0, "$NetBSD: dec_1000a.c,v 1.18 2002/09/27 15:35:33 provos Exp $");
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/device.h>
80 #include <sys/termios.h>
81 #include <sys/conf.h>
82 #include <dev/cons.h>
83 
84 #include <machine/rpb.h>
85 #include <machine/autoconf.h>
86 #include <machine/cpuconf.h>
87 #include <machine/bus.h>
88 
89 #include <dev/ic/comreg.h>
90 #include <dev/ic/comvar.h>
91 
92 #include <dev/isa/isareg.h>
93 #include <dev/isa/isavar.h>
94 #include <dev/ic/i8042reg.h>
95 #include <dev/ic/pckbcvar.h>
96 #include <dev/pci/pcireg.h>
97 #include <dev/pci/pcivar.h>
98 
99 #include <alpha/pci/apecsreg.h>
100 #include <alpha/pci/apecsvar.h>
101 #include <alpha/pci/ciareg.h>
102 #include <alpha/pci/ciavar.h>
103 
104 #include <dev/scsipi/scsi_all.h>
105 #include <dev/scsipi/scsipi_all.h>
106 #include <dev/scsipi/scsiconf.h>
107 
108 #include "pckbd.h"
109 
110 #ifndef CONSPEED
111 #define CONSPEED TTYDEF_SPEED
112 #endif
113 static int comcnrate = CONSPEED;
114 
115 void _dec_1000a_init __P((void));
116 static void dec_1000a_cons_init __P((void));
117 static void dec_1000a_device_register __P((struct device *, void *));
118 
119 #ifdef KGDB
120 #include <machine/db_machdep.h>
121 
122 static const char *kgdb_devlist[] = {
123 	"com",
124 	NULL,
125 };
126 #endif /* KGDB */
127 
128 static const struct alpha_variation_table dec_1000_variations[] = {
129 	{ 0, "AlphaServer 1000" },
130 	{ 0, NULL },
131 };
132 
133 static const struct alpha_variation_table dec_1000a_variations[] = {
134 	{ 0, "AlphaServer 1000A" },
135 	{ 0, NULL },
136 };
137 
138 void
139 _dec_1000a_init()
140 {
141 	u_int64_t variation;
142 
143 	platform.family = "AlphaServer 1000/1000A";
144 
145 	if ((platform.model = alpha_dsr_sysname()) == NULL) {
146 		variation = hwrpb->rpb_variation & SV_ST_MASK;
147 		if ((platform.model = alpha_variation_name(variation,
148 		    cputype == ST_DEC_1000 ? dec_1000_variations
149 					   : dec_1000a_variations)) == NULL)
150 			platform.model = alpha_unknown_sysname();
151 	}
152 
153 	switch(PCS_CPU_MAJORTYPE(LOCATE_PCS(hwrpb, 0))) {
154 	    case PCS_PROC_EV4:
155 	    case PCS_PROC_EV45:
156 		platform.iobus = "apecs";
157 		break;
158 	    default:
159 		platform.iobus = "cia";
160 		break;
161 	}
162 	platform.cons_init = dec_1000a_cons_init;
163 	platform.device_register = dec_1000a_device_register;
164 }
165 
166 static void
167 dec_1000a_cons_init()
168 {
169 	struct ctb *ctb;
170 	struct cia_config *ccp;
171 	struct apecs_config *acp;
172 	extern struct cia_config cia_configuration;
173 	extern struct apecs_config apecs_configuration;
174 	bus_space_tag_t iot, memt;
175 	struct alpha_pci_chipset *pcichipset;
176 
177 	if(strcmp(platform.iobus, "cia") == 0) {
178 		ccp = &cia_configuration;
179 		cia_init(ccp, 0);
180 		iot = &ccp->cc_iot;
181 		memt = &ccp->cc_memt;
182 		pcichipset = &ccp->cc_pc;
183 	} else {
184 		acp = &apecs_configuration;
185 		apecs_init(acp, 0);
186 		iot = &acp->ac_iot;
187 		memt = &acp->ac_memt;
188 		pcichipset = &acp->ac_pc;
189 	}
190 
191 	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
192 
193 	switch (ctb->ctb_term_type) {
194 	case CTB_PRINTERPORT:
195 		/* serial console ... */
196 		/* XXX */
197 		{
198 			/*
199 			 * Delay to allow PROM putchars to complete.
200 			 * FIFO depth * character time,
201 			 * character time = (1000000 / (defaultrate / 10))
202 			 */
203 			DELAY(160000000 / comcnrate);
204 
205 			if(comcnattach(iot, 0x3f8, comcnrate,
206 			    COM_FREQ,
207 			    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
208 				panic("can't init serial console");
209 
210 			break;
211 		}
212 
213 	case CTB_GRAPHICS:
214 #if NPCKBD > 0
215 		/* display console ... */
216 		/* XXX */
217 		(void) pckbc_cnattach(iot, IO_KBD, KBCMDP, PCKBC_KBD_SLOT);
218 
219 		/*
220 		 * AlphaServer 1000s have a firmware bug whereby the
221 		 * built-in ISA VGA is reported incorrectly -- ctb_turboslot
222 		 * is mostly 0.
223 		 */
224 		switch (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot)) {
225 		case CTB_TURBOSLOT_TYPE_PCI:
226 			pci_display_console(iot, memt, pcichipset,
227 			    CTB_TURBOSLOT_BUS(ctb->ctb_turboslot),
228 			    CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0);
229 			break;
230 
231 		default:
232 			isa_display_console(iot, memt);
233 			break;
234 		}
235 #else
236 		panic("not configured to use display && keyboard console");
237 #endif
238 		break;
239 
240 	default:
241 		printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
242 		printf("ctb->ctb_turboslot = 0x%lx\n", ctb->ctb_turboslot);
243 
244 		panic("consinit: unknown console type %ld",
245 		    ctb->ctb_term_type);
246 	}
247 #ifdef KGDB
248 	/* Attach the KGDB device. */
249 	alpha_kgdb_init(kgdb_devlist, iot);
250 #endif /* KGDB */
251 }
252 
253 static void
254 dec_1000a_device_register(dev, aux)
255 	struct device *dev;
256 	void *aux;
257 {
258 	static int found, initted, scsiboot, netboot;
259 	static struct device *pcidev, *scsidev;
260 	struct bootdev_data *b = bootdev_data;
261 	struct device *parent = dev->dv_parent;
262 	struct cfdata *cf = dev->dv_cfdata;
263 	const char *name = cf->cf_name;
264 
265 	if (found)
266 		return;
267 
268 	if (!initted) {
269 		scsiboot = (strcmp(b->protocol, "SCSI") == 0);
270 		netboot = (strcmp(b->protocol, "BOOTP") == 0) ||
271 		    (strcmp(b->protocol, "MOP") == 0);
272 #if 0
273 		printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
274 #endif
275 		initted =1;
276 	}
277 
278 	if (pcidev == NULL) {
279 		if (strcmp(name, "pci"))
280 			return;
281 		else {
282 			struct pcibus_attach_args *pba = aux;
283 
284 			if ((b->slot / 1000) != pba->pba_bus)
285 				return;
286 
287 			pcidev = dev;
288 #if 0
289 			printf("\npcidev = %s\n", pcidev->dv_xname);
290 #endif
291 			return;
292 		}
293 	}
294 
295 	if (scsiboot && (scsidev == NULL)) {
296 		if (parent != pcidev)
297 			return;
298 		else {
299 			struct pci_attach_args *pa = aux;
300 
301 			if ((b->slot % 1000) != pa->pa_device)
302 				return;
303 
304 			/* XXX function? */
305 
306 			scsidev = dev;
307 #if 0
308 			printf("\nscsidev = %s\n", scsidev->dv_xname);
309 #endif
310 			return;
311 		}
312 	}
313 
314 	if (scsiboot &&
315 	    (!strcmp(name, "sd") ||
316 	     !strcmp(name, "st") ||
317 	     !strcmp(name, "cd"))) {
318 		struct scsipibus_attach_args *sa = aux;
319 
320 		if (parent->dv_parent != scsidev)
321 			return;
322 
323 		if (b->unit / 100 != sa->sa_periph->periph_target)
324 			return;
325 
326 		/* XXX LUN! */
327 
328 		switch (b->boot_dev_type) {
329 		case 0:
330 			if (strcmp(name, "sd") &&
331 			    strcmp(name, "cd"))
332 				return;
333 			break;
334 		case 1:
335 			if (strcmp(name, "st"))
336 				return;
337 			break;
338 		default:
339 			return;
340 		}
341 
342 		/* we've found it! */
343 		booted_device = dev;
344 #if 0
345 		printf("\nbooted_device = %s\n", booted_device->dv_xname);
346 #endif
347 		found = 1;
348 	}
349 
350 	if (netboot) {
351 		if (parent != pcidev)
352 			return;
353 		else {
354 			struct pci_attach_args *pa = aux;
355 
356 			if ((b->slot % 1000) != pa->pa_device)
357 				return;
358 
359 			/* XXX function? */
360 
361 			booted_device = dev;
362 #if 0
363 			printf("\nbooted_device = %s\n", booted_device->dv_xname);
364 #endif
365 			found = 1;
366 			return;
367 		}
368 	}
369 }
370