xref: /netbsd-src/sys/arch/evbppc/obs405/obs200_machdep.c (revision 6de51c519f1b899da63c1bf576f478920b89083f)
1 /*	$NetBSD: obs200_machdep.c,v 1.19 2011/06/22 18:06:32 matt Exp $	*/
2 /*	Original: machdep.c,v 1.3 2005/01/17 17:24:09 shige Exp	*/
3 
4 /*
5  * Copyright 2001, 2002 Wasabi Systems, Inc.
6  * All rights reserved.
7  *
8  * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed for the NetBSD Project by
21  *      Wasabi Systems, Inc.
22  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23  *    or promote products derived from this software without specific prior
24  *    written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
41  * Copyright (C) 1995, 1996 TooLs GmbH.
42  * All rights reserved.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *	This product includes software developed by TooLs GmbH.
55  * 4. The name of TooLs GmbH may not be used to endorse or promote products
56  *    derived from this software without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
59  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
60  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
61  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
62  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
63  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
64  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
65  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
66  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
67  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68  */
69 
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: obs200_machdep.c,v 1.19 2011/06/22 18:06:32 matt Exp $");
72 
73 #include "opt_compat_netbsd.h"
74 #include "opt_ddb.h"
75 #include "opt_ipkdb.h"
76 
77 #include <sys/param.h>
78 #include <sys/kernel.h>
79 #include <sys/ksyms.h>
80 #include <sys/mount.h>
81 #include <sys/reboot.h>
82 #include <sys/systm.h>
83 #include <sys/device.h>
84 #include <sys/module.h>
85 #include <sys/bus.h>
86 #include <sys/cpu.h>
87 
88 #include <uvm/uvm_extern.h>
89 
90 #include <machine/obs200.h>
91 #include <machine/century_bios.h>
92 
93 #include <powerpc/spr.h>
94 #include <powerpc/ibm4xx/spr.h>
95 
96 #include <powerpc/ibm4xx/cpu.h>
97 #include <powerpc/ibm4xx/dcr4xx.h>
98 #include <powerpc/ibm4xx/ibm405gp.h>
99 #include <powerpc/ibm4xx/pci_machdep.h>
100 #include <powerpc/ibm4xx/dev/comopbvar.h>
101 
102 #include <dev/ic/comreg.h>
103 #include <dev/pci/pcivar.h>
104 #include <dev/pci/pciconf.h>
105 
106 #include "ksyms.h"
107 
108 #include "com.h"
109 #if (NCOM > 0)
110 #include <sys/termios.h>
111 
112 #ifndef CONADDR
113 #define CONADDR		IBM405GP_UART0_BASE
114 #endif
115 #ifndef CONSPEED
116 #define CONSPEED	B9600
117 #endif
118 #ifndef CONMODE
119 			/* 8N1 */
120 #define CONMODE		((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
121 #endif
122 #endif	/* NCOM */
123 
124 #define	TLB_PG_SIZE 	(16*1024*1024)
125 
126 /*
127  * Global variables used here and there
128  */
129 char bootpath[256];
130 
131 extern paddr_t msgbuf_paddr;
132 
133 void initppc(vaddr_t, vaddr_t, char *, void *);
134 
135 void
136 initppc(vaddr_t startkernel, vaddr_t endkernel, char *args, void *info_block)
137 {
138 	u_int32_t pllmode;
139 	u_int32_t psr;
140 	vaddr_t va;
141 	u_int memsize;
142 
143 	/* Disable all external interrupts */
144 	mtdcr(DCR_UIC0_BASE + DCR_UIC_ER, 0);
145 	pllmode = mfdcr(DCR_CPC0_PLLMR);
146 	psr = mfdcr(DCR_CPC0_PSR);
147 
148 	/* Setup board from BIOS */
149 	bios_board_init(info_block, startkernel);
150 	memsize = bios_board_memsize_get();
151 
152 	/* Linear map kernel memory. */
153 	for (va = 0; va < endkernel; va += TLB_PG_SIZE)
154 		ppc4xx_tlb_reserve(va, va, TLB_PG_SIZE, TLB_EX);
155 
156 	/* Map console after physmem (see pmap_tlbmiss()). */
157 	ppc4xx_tlb_reserve(CONADDR, roundup(memsize, TLB_PG_SIZE), TLB_PG_SIZE,
158 	    TLB_I | TLB_G);
159 
160 	/* Initialize IBM405GPr CPU */
161 	ibm40x_memsize_init(memsize, startkernel);
162 	ibm4xx_init(startkernel, endkernel, pic_ext_intr);
163 
164 #ifdef DEBUG
165 	bios_board_print();
166 	printf("  PLL Mode Register = 0x%08x\n", pllmode);
167 	printf("  Chip Pin Strapping Register = 0x%08x\n", psr);
168 #endif
169 
170 #ifdef DDB
171 	if (boothowto & RB_KDB)
172 		Debugger();
173 #endif
174 #ifdef IPKDB
175 	/*
176 	 * Now trap to IPKDB
177 	 */
178 	ipkdb_init();
179 	if (boothowto & RB_KDB)
180 		ipkdb_connect(0);
181 #endif
182 
183 	/*
184 	 * Look for the ibm4xx modules in the right place.
185 	 */
186 	module_machine = module_machine_ibm4xx;
187 }
188 
189 void
190 consinit(void)
191 {
192 
193 #if (NCOM > 0)
194 	com_opb_cnattach(OBS200_COM_FREQ, CONADDR, CONSPEED, CONMODE);
195 #endif
196 }
197 
198 /*
199  * Machine dependent startup code.
200  */
201 void
202 cpu_startup(void)
203 {
204 
205 	/*
206 	 * cpu common startup
207 	 */
208 	ibm4xx_cpu_startup("OpenBlockS S/R IBM PowerPC 405GP Board");
209 
210 	/*
211 	 * Set up the board properties database.
212 	 */
213 	bios_board_info_set();
214 
215 	/*
216 	 * Now that we have VM, malloc()s are OK in bus_space.
217 	 */
218 	bus_space_mallocok();
219 
220 	/*
221 	 * no fake mapiodev
222 	 */
223 	fake_mapiodev = 0;
224 }
225 
226 /*
227  * Halt or reboot the machine after syncing/dumping according to howto.
228  */
229 void
230 cpu_reboot(int howto, char *what)
231 {
232 	static int syncing;
233 	static char str[256];
234 	char *ap = str, *ap1 = ap;
235 
236 	boothowto = howto;
237 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
238 		syncing = 1;
239 		vfs_shutdown();		/* sync */
240 		resettodr();		/* set wall clock */
241 	}
242 
243 	splhigh();
244 
245 	if (!cold && (howto & RB_DUMP))
246 		ibm4xx_dumpsys();
247 
248 	doshutdownhooks();
249 
250 	pmf_system_shutdown(boothowto);
251 
252 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
253 	  /* Power off here if we know how...*/
254 	}
255 
256 	if (howto & RB_HALT) {
257 		printf("halted\n\n");
258 
259 #if 0
260 		goto reboot;	/* XXX for now... */
261 #endif
262 
263 #ifdef DDB
264 		printf("dropping to debugger\n");
265 		while(1)
266 			Debugger();
267 #endif
268 	}
269 
270 	printf("rebooting\n\n");
271 	if (what && *what) {
272 		if (strlen(what) > sizeof str - 5)
273 			printf("boot string too large, ignored\n");
274 		else {
275 			strcpy(str, what);
276 			ap1 = ap = str + strlen(str);
277 			*ap++ = ' ';
278 		}
279 	}
280 	*ap++ = '-';
281 	if (howto & RB_SINGLE)
282 		*ap++ = 's';
283 	if (howto & RB_KDB)
284 		*ap++ = 'd';
285 	*ap++ = 0;
286 	if (ap[-2] == '-')
287 		*ap1 = 0;
288 
289 	/* flush cache for msgbuf */
290 	__syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE));
291 
292 #if 0
293  reboot:
294 #endif
295 	ppc4xx_reset();
296 
297 	printf("ppc4xx_reset() failed!\n");
298 #ifdef DDB
299 	while(1)
300 		Debugger();
301 #else
302 	while (1)
303 		/* nothing */;
304 #endif
305 }
306 
307 int
308 ibm4xx_pci_bus_maxdevs(void *v, int busno)
309 {
310 
311 	/*
312 	 * Bus number is irrelevant.  Configuration Mechanism 1 is in
313 	 * use, can have devices 0-32 (i.e. the `normal' range).
314 	 */
315 	return 31;
316 }
317 
318 int
319 ibm4xx_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
320 {
321 	/*
322 	 * We need to map the interrupt pin to the interrupt bit
323 	 * in the UIC associated with it.
324 	 *
325 	 * This platform has 4 PCI devices.
326 	 *
327 	 # External IRQ Mappings:
328 	 *  dev 7 (Ext IRQ3):	Realtek 8139 Ethernet
329 	 *  dev 8 (Ext IRQ0):	PCI Connector
330 	 */
331 	static const int irqmap[15/*device*/][4/*pin*/] = {
332 		{ -1, -1, -1, -1 },	/*  1: none */
333 		{ -1, -1, -1, -1 },	/*  2: none */
334 		{ -1, -1, -1, -1 },	/*  3: none */
335 		{ -1, -1, -1, -1 },	/*  4: none */
336 		{ -1, -1, -1, -1 },	/*  5: none */
337 		{ -1, -1, -1, -1 },	/*  6: none */
338 		{  3, -1, -1, -1 },	/*  7: none */
339 		{  0, -1, -1, -1 },	/*  8: none */
340 		{ -1, -1, -1, -1 },	/*  9: none */
341 		{ -1, -1, -1, -1 },	/* 10: none */
342 		{ -1, -1, -1, -1 },	/* 11: none */
343 		{ -1, -1, -1, -1 },	/* 12: none */
344 		{ -1, -1, -1, -1 },	/* 13: none */
345 		{ -1, -1, -1, -1 },	/* 14: none */
346 		{ -1, -1, -1, -1 },	/* 15: none */
347 	};
348 
349 	int pin, dev, irq;
350 
351 	pin = pa->pa_intrpin;
352 	dev = pa->pa_device;
353         *ihp = -1;
354 
355 	/* if interrupt pin not used... */
356 	if (pin == 0)
357 		return 1;
358 
359 	if (pin > 4) {
360 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
361 		return 1;
362 	}
363 
364 	if ((dev < 1) || (dev > 15)) {
365 		printf("pci_intr_map: bad device %d\n", dev);
366 		return 1;
367 	}
368 
369 
370 	if ((irq = irqmap[dev - 1][pin - 1]) == -1) {
371 		printf("pci_intr_map: no IRQ routing for device %d pin %d\n",
372 			dev, pin);
373 		return 1;
374 	}
375 
376 	*ihp = irq + 25;
377 	return 0;
378 }
379 
380 void
381 ibm4xx_pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz,
382     int *iline)
383 {
384 	static const int ilinemap[15/*device*/] = {
385 		-1, -1, -1, -1,		/* device  1 -  4 */
386 		-1, -1, 28, 25,		/* device  5 -  8 */
387 		-1, -1, -1, -1,		/* device  9 - 12 */
388 		-1, -1, -1,		/* device 13 - 15 */
389 	};
390 
391 	if (bus == 0) {
392 		if ((dev < 1) || (dev > 15)) {
393 			printf("pci_intr_map: bad device %d\n", dev);
394 			*iline = 0;
395 			return;
396 		}
397 		*iline = ilinemap[dev - 1];
398 	} else
399 		*iline = 19 + ((swiz + dev + 1) & 3);
400 }
401