xref: /netbsd-src/sys/arch/bebox/bebox/machdep.c (revision f36002f244a49908fef9cba8789032bdbf48d572)
1 /*	$NetBSD: machdep.c,v 1.110 2024/03/05 14:15:29 thorpej Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5  * Copyright (C) 1995, 1996 TooLs GmbH.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by TooLs GmbH.
19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.110 2024/03/05 14:15:29 thorpej Exp $");
36 
37 #include "opt_compat_netbsd.h"
38 #include "opt_ddb.h"
39 
40 #define _POWERPC_BUS_DMA_PRIVATE
41 
42 #include <sys/param.h>
43 #include <sys/bus.h>
44 #include <sys/conf.h>
45 #include <sys/device.h>
46 #include <sys/kernel.h>
47 #include <sys/mount.h>
48 #include <sys/reboot.h>
49 #include <sys/systm.h>
50 #include <sys/vnode.h>
51 
52 #include <uvm/uvm_extern.h>
53 
54 #include <machine/bebox.h>
55 #include <machine/autoconf.h>
56 #include <machine/bootinfo.h>
57 #include <machine/powerpc.h>
58 
59 #include <powerpc/bat.h>
60 #include <powerpc/pic/picvar.h>
61 #include <powerpc/pio.h>
62 #include <powerpc/prep_bus.h>
63 #include <powerpc/psl.h>
64 
65 #include <dev/cons.h>
66 
67 #include "vga.h"
68 #if (NVGA > 0)
69 #include <dev/ic/mc6845reg.h>
70 #include <dev/ic/pcdisplayvar.h>
71 #include <dev/ic/vgareg.h>
72 #include <dev/ic/vgavar.h>
73 #endif
74 
75 #include "pckbc.h"
76 #if (NPCKBC > 0)
77 #include <dev/isa/isareg.h>
78 #include <dev/ic/i8042reg.h>
79 #include <dev/ic/pckbcvar.h>
80 #include <dev/pckbport/pckbportvar.h>
81 #endif
82 
83 #include "com.h"
84 #if (NCOM > 0)
85 #include <sys/termios.h>
86 #include <dev/ic/comreg.h>
87 #include <dev/ic/comvar.h>
88 #endif
89 
90 /*
91  * Global variables used here and there
92  */
93 char bootinfo[BOOTINFO_MAXSIZE];
94 #define	MEMREGIONS	2
95 struct mem_region physmemr[MEMREGIONS], availmemr[MEMREGIONS];
96 char bootpath[256];
97 struct pic_ops *isa_pic;
98 extern int primary_pic;
99 void initppc(u_long, u_long, u_int, void *);
100 static void disable_device(const char *);
101 void setup_bebox_intr(void);
102 
103 extern void *startsym, *endsym;
104 
105 void
initppc(u_long startkernel,u_long endkernel,u_int args,void * btinfo)106 initppc(u_long startkernel, u_long endkernel, u_int args, void *btinfo)
107 {
108 	/*
109 	 * copy bootinfo
110 	 */
111 	memcpy(bootinfo, btinfo, sizeof (bootinfo));
112 
113 	/*
114 	 * BeBox memory region set
115 	 */
116 	{
117 		struct btinfo_memory *meminfo;
118 
119 		meminfo =
120 		    (struct btinfo_memory *)lookup_bootinfo(BTINFO_MEMORY);
121 		if (!meminfo)
122 			panic("not found memory information in bootinfo");
123 		physmemr[0].start = 0;
124 		physmemr[0].size = meminfo->memsize & ~PGOFSET;
125 		availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET;
126 		availmemr[0].size = meminfo->memsize - availmemr[0].start;
127 	}
128 
129 	/*
130 	 * Get CPU clock
131 	 */
132 	{
133 		struct btinfo_clock *clockinfo;
134 		extern u_long ticks_per_sec, ns_per_tick;
135 
136 		clockinfo =
137 		    (struct btinfo_clock *)lookup_bootinfo(BTINFO_CLOCK);
138 		if (!clockinfo)
139 			panic("not found clock information in bootinfo");
140 		ticks_per_sec = clockinfo->ticks_per_sec;
141 		ns_per_tick = 1000000000 / ticks_per_sec;
142 	}
143 
144 	prep_initppc(startkernel, endkernel, args,
145 	    /* BeBox mainboard registers */
146 	    0x7ffff000, BAT_BL_8M,		/* XXX magic number */
147 	    0);
148 }
149 
150 /*
151  * Machine dependent startup code.
152  */
153 void
cpu_startup(void)154 cpu_startup(void)
155 {
156 
157 	/*
158 	 * Do common VM initialization
159 	 */
160 	oea_startup(NULL);
161 
162 	pic_init();
163 	isa_pic = setup_i8259();
164 	setup_bebox_intr();
165 	primary_pic = 1;
166 
167 	/*
168 	 * set up i8259 as a cascade on BeInterruptController irq 26.
169 	 */
170 	intr_establish(16 + 26, IST_LEVEL, IPL_HIGH, pic_handle_intr, isa_pic);
171 
172 	oea_install_extint(pic_ext_intr);
173 
174 	/*
175 	 * Now that we have VM, malloc's are OK in bus_space.
176 	 */
177 	bus_space_mallocok();
178 }
179 
180 /*
181  * lookup_bootinfo:
182  * Look up information in bootinfo of boot loader.
183  */
184 void *
lookup_bootinfo(int type)185 lookup_bootinfo(int type)
186 {
187 	struct btinfo_common *bt;
188 	struct btinfo_common *help = (struct btinfo_common *)bootinfo;
189 
190 	do {
191 		bt = help;
192 		if (bt->type == type)
193 			return (help);
194 		help = (struct btinfo_common *)((char*)help + bt->next);
195 	} while (bt->next &&
196 	    (size_t)help < (size_t)bootinfo + sizeof (bootinfo));
197 
198 	return (NULL);
199 }
200 
201 static void
disable_device(const char * name)202 disable_device(const char *name)
203 {
204 	extern struct cfdata cfdata[];
205 	int i;
206 
207 	for (i = 0; cfdata[i].cf_name != NULL; i++)
208 		if (strcmp(cfdata[i].cf_name, name) == 0) {
209 			if (cfdata[i].cf_fstate == FSTATE_NOTFOUND)
210 				cfdata[i].cf_fstate = FSTATE_DNOTFOUND;
211 			else if (cfdata[i].cf_fstate == FSTATE_STAR)
212 				cfdata[i].cf_fstate = FSTATE_DSTAR;
213 		}
214 }
215 
216 /*
217  * consinit
218  * Initialize system console.
219  */
220 void
consinit(void)221 consinit(void)
222 {
223 	struct btinfo_console *consinfo;
224 	static int initted;
225 
226 	if (initted)
227 		return;
228 	initted = 1;
229 
230 	consinfo = (struct btinfo_console *)lookup_bootinfo(BTINFO_CONSOLE);
231 	if (!consinfo)
232 		panic("not found console information in bootinfo");
233 
234 	/*
235 	 * We need to disable genfb or vga, because foo_match() return
236 	 * the same value.
237 	 */
238 	if (!strcmp(consinfo->devname, "be")) {
239 		/*
240 		 * We use Framebuffer for initialized by BootROM of BeBox.
241 		 * In this case, our console will be attached more late.
242 		 */
243 #if (NPCKBC > 0)
244 		pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP,
245 		    PCKBC_KBD_SLOT, 0);
246 #endif
247 		disable_device("vga");
248 		return;
249 	}
250 
251 	disable_device("genfb");
252 
253 #if (NVGA > 0)
254 	if (!strcmp(consinfo->devname, "vga")) {
255 		vga_cnattach(&prep_io_space_tag, &prep_mem_space_tag, -1, 1);
256 #if (NPCKBC > 0)
257 		pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP,
258 		    PCKBC_KBD_SLOT, 0);
259 #endif
260 		return;
261 	}
262 #endif
263 
264 #if (NCOM > 0)
265 	if (!strcmp(consinfo->devname, "com")) {
266 	   	bus_space_tag_t tag = &genppc_isa_io_space_tag;
267 
268 		if(comcnattach(tag, consinfo->addr, consinfo->speed,
269 		    COM_FREQ, COM_TYPE_NORMAL,
270 		    ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)))
271 			panic("can't init serial console");
272 		return;
273 	}
274 #endif
275 	panic("invalid console device %s", consinfo->devname);
276 }
277 
278 /*
279  * Halt or reboot the machine after syncing/dumping according to howto.
280  */
281 void
cpu_reboot(int howto,char * what)282 cpu_reboot(int howto, char *what)
283 {
284 	static int syncing;
285 	static char str[256];
286 	char *ap = str, *ap1 = ap;
287 
288 	boothowto = howto;
289 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
290 		syncing = 1;
291 		vfs_shutdown();		/* sync */
292 	}
293 	splhigh();
294 	if (howto & RB_HALT) {
295 		doshutdownhooks();
296 		pmf_system_shutdown(boothowto);
297 		printf("halted\n\n");
298 
299 	}
300 	if (!cold && (howto & RB_DUMP))
301 		oea_dumpsys();
302 	doshutdownhooks();
303 	pmf_system_shutdown(boothowto);
304 	printf("rebooting\n\n");
305 	if (what && *what) {
306 		if (strlen(what) > sizeof str - 5)
307 			printf("boot string too large, ignored\n");
308 		else {
309 			strcpy(str, what);
310 			ap1 = ap = str + strlen(str);
311 			*ap++ = ' ';
312 		}
313 	}
314 	*ap++ = '-';
315 	if (howto & RB_SINGLE)
316 		*ap++ = 's';
317 	if (howto & RB_KDB)
318 		*ap++ = 'd';
319 	*ap++ = 0;
320 	if (ap[-2] == '-')
321 		*ap1 = 0;
322 
323 	/* Left and Right LED on.  Max 15 for both LED. */
324 #define LEFT_LED(x)	(((x) & 0xf) << 4)
325 #define RIGHT_LED(x)	(((x) & 0xf))
326 
327 	outb(PREP_BUS_SPACE_IO + 0x0c00, LEFT_LED(15) | RIGHT_LED(15));
328 
329 	while (1);
330 }
331