dec_6600.c revision 1.1
1/* $NetBSD: dec_6600.c,v 1.1 1999/06/29 07:08:53 ross Exp $ */
2
3/*
4 * Copyright (c) 1995, 1996, 1997 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#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
31
32__KERNEL_RCSID(0, "$NetBSD: dec_6600.c,v 1.1 1999/06/29 07:08:53 ross Exp $");
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
40#include <machine/rpb.h>
41#include <machine/autoconf.h>
42#include <machine/conf.h>
43#include <machine/bus.h>
44
45#include <dev/ic/comreg.h>
46#include <dev/ic/comvar.h>
47
48#include <dev/isa/isavar.h>
49#include <dev/isa/pckbcvar.h>
50#include <dev/pci/pcireg.h>
51#include <dev/pci/pcivar.h>
52
53#include <alpha/pci/tsreg.h>
54#include <alpha/pci/tsvar.h>
55
56#include <dev/scsipi/scsi_all.h>
57#include <dev/scsipi/scsipi_all.h>
58#include <dev/scsipi/scsiconf.h>
59
60#include "pckbd.h"
61
62#ifndef CONSPEED
63#define CONSPEED TTYDEF_SPEED
64#endif
65
66#define	DR_VERBOSE(f) while (0)
67
68static int comcnrate __attribute__((unused)) = CONSPEED;
69
70void dec_6600_init __P((void));
71static void dec_6600_cons_init __P((void));
72static void dec_6600_device_register __P((struct device *, void *));
73
74void
75dec_6600_init()
76{
77
78	platform.family = "6600";
79
80	if ((platform.model = alpha_dsr_sysname()) == NULL) {
81		/* XXX Don't know the system variations, yet. */
82		platform.model = alpha_unknown_sysname();
83	}
84
85	platform.iobus = "tsc";
86	platform.cons_init = dec_6600_cons_init;
87	platform.device_register = dec_6600_device_register;
88	STQP(TS_C_DIM0) = 0UL;
89	STQP(TS_C_DIM1) = 0UL;
90}
91
92static void
93dec_6600_cons_init()
94{
95	struct ctb *ctb;
96	u_int64_t ctbslot;
97	struct tsp_config *tsp;
98
99	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
100	ctbslot = ctb->ctb_turboslot;
101
102	tsp = tsp_init(0, 0);
103
104	switch (ctb->ctb_term_type) {
105	case 2:
106		/* serial console ... */
107		assert(CTB_TURBOSLOT_HOSE(ctbslot) == 0);
108		/* XXX */
109		{
110			/*
111			 * Delay to allow PROM putchars to complete.
112			 * FIFO depth * character time,
113			 * character time = (1000000 / (defaultrate / 10))
114			 */
115			DELAY(160000000 / comcnrate);
116
117			if(comcnattach(&tsp->pc_iot, 0x3f8, comcnrate,
118			    COM_FREQ,
119			    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
120				panic("can't init serial console");
121
122			break;
123		}
124
125	case 3:
126#if NPCKBD > 0
127		/* display console ... */
128		/* XXX */
129		(void) pckbc_cnattach(&tsp->pc_iot, PCKBC_KBD_SLOT);
130
131		if (CTB_TURBOSLOT_TYPE(ctbslot) ==
132		    CTB_TURBOSLOT_TYPE_ISA)
133			isa_display_console(&tsp->pc_iot, &tsp->pc_memt);
134		else {
135			/* The display PCI might be different */
136			tsp = tsp_init(0, CTB_TURBOSLOT_HOSE(ctbslot));
137			pci_display_console(&tsp->pc_iot, &tsp->pc_memt,
138			    &tsp->pc_pc, CTB_TURBOSLOT_BUS(ctbslot),
139			    CTB_TURBOSLOT_SLOT(ctbslot), 0);
140		}
141#else
142		panic("not configured to use display && keyboard console");
143#endif
144		break;
145
146	default:
147		printf("ctb_term_type = 0x%lx ctb_turboslot = 0x%lx"
148		    " hose = %ld\n", ctb->ctb_term_type, ctbslot,
149		    CTB_TURBOSLOT_HOSE(ctbslot));
150
151		panic("consinit: unknown console type %ld\n",
152		    ctb->ctb_term_type);
153	}
154}
155
156static void
157dec_6600_device_register(dev, aux)
158	struct device *dev;
159	void *aux;
160{
161	static int found, initted, scsiboot, ideboot, netboot;
162	static struct device *primarydev, *pcidev, *scsipidev;
163	struct bootdev_data *b = bootdev_data;
164	struct device *parent = dev->dv_parent;
165	struct cfdata *cf = dev->dv_cfdata;
166	struct cfdriver *cd = cf->cf_driver;
167
168	if (found)
169		return;
170
171	if (!initted) {
172		scsiboot = (strcmp(b->protocol, "SCSI") == 0);
173		netboot = (strcmp(b->protocol, "BOOTP") == 0);
174		/*
175		 * Add an extra check to boot from ide drives:
176		 * Newer SRM firmware use the protocol identifier IDE,
177		 * older SRM firmware use the protocol identifier SCSI.
178		 */
179		ideboot = (strcmp(b->protocol, "IDE") == 0);
180		DR_VERBOSE(printf("scsiboot = %d, ideboot = %d, netboot = %d\n",
181		    scsiboot, ideboot, netboot));
182		initted = 1;
183	}
184	if (primarydev == NULL) {
185		if (strcmp(cd->cd_name, "tsp"))
186			return;
187		else {
188			struct tsp_attach_args *tsp = aux;
189
190			if (b->bus != tsp->tsp_slot)
191				return;
192			primarydev = dev;
193			DR_VERBOSE(printf("\nprimarydev = %s\n",
194			    primarydev->dv_xname));
195			return;
196		}
197	}
198	if (pcidev == NULL) {
199		if (parent != primarydev)
200			return;
201		if (strcmp(cd->cd_name, "pci"))
202			return;
203		else {
204			struct pcibus_attach_args *pba = aux;
205
206			if ((b->slot / 1000) != pba->pba_bus)
207				return;
208
209			pcidev = dev;
210			DR_VERBOSE(printf("\npcidev = %s\n", pcidev->dv_xname));
211			return;
212		}
213	}
214	if ((ideboot || scsiboot) && scsipidev == NULL) {
215		if (parent != pcidev)
216			return;
217		else {
218			struct pci_attach_args *pa = aux;
219
220			if (b->slot % 1000 / 100 != pa->pa_function)
221				return;
222			if (b->slot % 100 != pa->pa_device)
223				return;
224
225			scsipidev = dev;
226			DR_VERBOSE(printf("\nscsipidev = %s\n",
227			    scsipidev->dv_xname));
228			return;
229		}
230	}
231	if ((scsiboot || ideboot) &&
232	    (!strcmp(cd->cd_name, "sd") ||
233	     !strcmp(cd->cd_name, "st") ||
234	     !strcmp(cd->cd_name, "cd"))) {
235		struct scsipibus_attach_args *sa = aux;
236
237		if (parent->dv_parent != scsipidev)
238			return;
239
240		if (b->unit / 100 != sa->sa_sc_link->scsipi_scsi.target)
241			return;
242
243		/* XXX LUN! */
244
245		switch (b->boot_dev_type) {
246		case 0:
247			if (strcmp(cd->cd_name, "sd") &&
248			    strcmp(cd->cd_name, "cd"))
249				return;
250			break;
251		case 1:
252			if (strcmp(cd->cd_name, "st"))
253				return;
254			break;
255		default:
256			return;
257		}
258
259		/* we've found it! */
260		booted_device = dev;
261		DR_VERBOSE(printf("\nbooted_device = %s\n",
262		    booted_device->dv_xname));
263		found = 1;
264	}
265
266	/*
267	 * Support to boot from IDE drives.
268	 * Should work with all SRM firmware versions, but is at the
269	 * moment limited to hard disks. Support for IDE CD ROM is
270	 * included above, under the theory that it will always be
271	 * via the pci ide controller.
272	 */
273	if ((ideboot || scsiboot) && !strcmp(cd->cd_name, "wd")) {
274		if ((strncmp("pciide", parent->dv_xname, 6) != 0)) {
275			return;
276		} else {
277			if (parent != scsipidev)
278				return;
279		}
280
281		/* we've found it! */
282		booted_device = dev;
283		DR_VERBOSE(printf("\nbooted_device = %s\n",
284		    booted_device->dv_xname));
285		found = 1;
286	}
287	if (netboot) {
288		if (parent != pcidev)
289			return;
290		else {
291			struct pci_attach_args *pa = aux;
292
293			if (b->slot % 1000 / 100 != pa->pa_function)
294				return;
295			if ((b->slot % 100) != pa->pa_device)
296				return;
297
298			booted_device = dev;
299			DR_VERBOSE(printf("\nbooted_device = %s\n",
300			    booted_device->dv_xname));
301			found = 1;
302			return;
303		}
304	}
305}
306