Home | History | Annotate | Line # | Download | only in ofppc
machdep.c revision 1.86
      1  1.86     lukem /*	$NetBSD: machdep.c,v 1.86 2003/07/15 02:46:32 lukem Exp $	*/
      2   1.1        ws 
      3   1.1        ws /*
      4   1.1        ws  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
      5   1.1        ws  * Copyright (C) 1995, 1996 TooLs GmbH.
      6   1.1        ws  * All rights reserved.
      7   1.1        ws  *
      8   1.1        ws  * Redistribution and use in source and binary forms, with or without
      9   1.1        ws  * modification, are permitted provided that the following conditions
     10   1.1        ws  * are met:
     11   1.1        ws  * 1. Redistributions of source code must retain the above copyright
     12   1.1        ws  *    notice, this list of conditions and the following disclaimer.
     13   1.1        ws  * 2. Redistributions in binary form must reproduce the above copyright
     14   1.1        ws  *    notice, this list of conditions and the following disclaimer in the
     15   1.1        ws  *    documentation and/or other materials provided with the distribution.
     16   1.1        ws  * 3. All advertising materials mentioning features or use of this software
     17   1.1        ws  *    must display the following acknowledgement:
     18   1.1        ws  *	This product includes software developed by TooLs GmbH.
     19   1.1        ws  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     20   1.1        ws  *    derived from this software without specific prior written permission.
     21   1.1        ws  *
     22   1.1        ws  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     23   1.1        ws  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24   1.1        ws  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25   1.1        ws  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26   1.1        ws  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27   1.1        ws  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     28   1.1        ws  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     29   1.1        ws  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     30   1.1        ws  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     31   1.1        ws  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32   1.1        ws  */
     33  1.86     lukem 
     34  1.86     lukem #include <sys/cdefs.h>
     35  1.86     lukem __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.86 2003/07/15 02:46:32 lukem Exp $");
     36  1.21  jonathan 
     37  1.27   thorpej #include "opt_compat_netbsd.h"
     38  1.21  jonathan #include "opt_ddb.h"
     39   1.1        ws 
     40   1.1        ws #include <sys/param.h>
     41   1.1        ws #include <sys/buf.h>
     42   1.1        ws #include <sys/exec.h>
     43   1.1        ws #include <sys/malloc.h>
     44   1.1        ws #include <sys/mbuf.h>
     45   1.1        ws #include <sys/mount.h>
     46   1.1        ws #include <sys/msgbuf.h>
     47   1.1        ws #include <sys/proc.h>
     48   1.1        ws #include <sys/reboot.h>
     49  1.80   thorpej #include <sys/sa.h>
     50   1.1        ws #include <sys/syscallargs.h>
     51   1.1        ws #include <sys/syslog.h>
     52   1.1        ws #include <sys/systm.h>
     53  1.43   thorpej #include <sys/kernel.h>
     54   1.1        ws #include <sys/user.h>
     55  1.59  jdolecek #include <sys/boot_flag.h>
     56  1.84     ragge #include <sys/ksyms.h>
     57   1.1        ws 
     58  1.19  sakamoto #include <uvm/uvm_extern.h>
     59  1.19  sakamoto 
     60   1.1        ws #include <net/netisr.h>
     61   1.1        ws 
     62  1.72   thorpej #include <machine/db_machdep.h>
     63  1.72   thorpej #include <ddb/db_extern.h>
     64  1.72   thorpej 
     65  1.70   thorpej #include <dev/ofw/openfirm.h>
     66  1.70   thorpej 
     67  1.68      matt #include <machine/autoconf.h>
     68   1.1        ws #include <machine/bat.h>
     69   1.1        ws #include <machine/pmap.h>
     70   1.1        ws #include <machine/powerpc.h>
     71   1.1        ws #include <machine/trap.h>
     72  1.54   thorpej 
     73  1.71   thorpej #include <machine/platform.h>
     74  1.71   thorpej 
     75  1.68      matt #include <dev/cons.h>
     76   1.1        ws 
     77  1.84     ragge #include "ksyms.h"
     78   1.1        ws /*
     79   1.1        ws  * Global variables used here and there
     80   1.1        ws  */
     81  1.78       chs char bootpath[256];
     82   1.1        ws 
     83  1.76      matt int lcsplx(int);			/* called from locore.S */
     84  1.60   thorpej 
     85  1.73   thorpej static int fake_spl __P((int));
     86  1.73   thorpej static void fake_splx __P((int));
     87  1.73   thorpej static void fake_setsoft __P((int));
     88   1.7   thorpej static void fake_clock_return __P((struct clockframe *, int));
     89  1.73   thorpej static void *fake_intr_establish __P((int, int, int, int (*)(void *), void *));
     90  1.73   thorpej static void fake_intr_disestablish __P((void *));
     91   1.1        ws 
     92   1.1        ws struct machvec machine_interface = {
     93  1.44  wrstuden 	fake_spl,
     94   1.7   thorpej 	fake_spl,
     95   1.1        ws 	fake_splx,
     96   1.7   thorpej 	fake_setsoft,
     97   1.7   thorpej 	fake_clock_return,
     98  1.73   thorpej 	fake_intr_establish,
     99  1.73   thorpej 	fake_intr_disestablish,
    100   1.1        ws };
    101   1.1        ws 
    102  1.71   thorpej void	ofppc_bootstrap_console(void);
    103  1.77      matt 
    104  1.77      matt struct pmap ofw_pmap;
    105  1.70   thorpej 
    106   1.1        ws void
    107   1.1        ws initppc(startkernel, endkernel, args)
    108   1.1        ws 	u_int startkernel, endkernel;
    109   1.1        ws 	char *args;
    110   1.1        ws {
    111  1.84     ragge #if NKSYMS || defined(DDB) || defined(LKM)
    112  1.72   thorpej 	extern void *startsym, *endsym;
    113  1.14  sakamoto #endif
    114   1.1        ws 
    115  1.71   thorpej 	/* Initialize the bootstrap console. */
    116  1.71   thorpej 	ofppc_bootstrap_console();
    117  1.71   thorpej 
    118   1.1        ws 	/*
    119  1.76      matt 	 * Initialize the bat registers
    120   1.1        ws 	 */
    121  1.82      matt 	oea_batinit(0);
    122  1.29  sakamoto 
    123   1.1        ws 	/*
    124  1.73   thorpej 	 * Initialize the platform structure.  This may add entries
    125  1.73   thorpej 	 * to the BAT table.
    126  1.73   thorpej 	 */
    127  1.73   thorpej 	platform_init();
    128  1.73   thorpej 
    129  1.73   thorpej #ifdef __notyet__	/* Needs some rethinking regarding real/virtual OFW */
    130  1.73   thorpej 	OF_set_callback(callback);
    131  1.73   thorpej #endif
    132  1.73   thorpej 
    133  1.82      matt 	oea_init(NULL);
    134   1.1        ws 
    135   1.1        ws 	/*
    136  1.73   thorpej 	 * Now that translation is enabled (and we can access bus space),
    137  1.73   thorpej 	 * initialize the console.
    138  1.73   thorpej 	 */
    139  1.73   thorpej 	(*platform.cons_init)();
    140  1.73   thorpej 
    141  1.73   thorpej 	/*
    142   1.1        ws 	 * Parse arg string.
    143   1.1        ws 	 */
    144  1.78       chs 	strcpy(bootpath, args);
    145   1.7   thorpej 	while (*++args && *args != ' ');
    146   1.1        ws 	if (*args) {
    147  1.59  jdolecek 		for(*args++ = 0; *args; args++)
    148  1.59  jdolecek 			BOOT_FLAG(*args, boothowto);
    149  1.29  sakamoto 	}
    150   1.1        ws 
    151  1.72   thorpej 	/*
    152  1.72   thorpej 	 * Set the page size.
    153  1.72   thorpej 	 */
    154  1.72   thorpej 	uvm_setpagesize();
    155  1.72   thorpej 
    156  1.72   thorpej 	/*
    157  1.72   thorpej 	 * Initialize pmap module.
    158  1.72   thorpej 	 */
    159  1.81    kleink 	pmap_bootstrap(startkernel, endkernel);
    160  1.72   thorpej 
    161  1.84     ragge #if NKSYMS || defined(DDB) || defined(LKM)
    162  1.84     ragge 	ksyms_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
    163  1.84     ragge #endif
    164  1.14  sakamoto #ifdef DDB
    165  1.72   thorpej 	if (boothowto & RB_KDB)
    166  1.72   thorpej 		Debugger();
    167  1.14  sakamoto #endif
    168  1.53        ws #ifdef IPKDB
    169   1.1        ws 	/*
    170   1.4        ws 	 * Now trap to IPKDB
    171   1.1        ws 	 */
    172   1.4        ws 	ipkdb_init();
    173   1.1        ws 	if (boothowto & RB_KDB)
    174   1.4        ws 		ipkdb_connect(0);
    175   1.1        ws #endif
    176   1.1        ws }
    177   1.1        ws 
    178   1.1        ws /*
    179   1.1        ws  * Machine dependent startup code.
    180   1.1        ws  */
    181   1.1        ws void
    182   1.1        ws cpu_startup()
    183   1.1        ws {
    184  1.78       chs 
    185  1.82      matt 	oea_startup(NULL);
    186   1.1        ws 
    187   1.1        ws 	/*
    188   1.1        ws 	 * Now allow hardware interrupts.
    189   1.1        ws 	 */
    190  1.76      matt 	splhigh();
    191  1.78       chs 	mtmsr(mfmsr() | PSL_EE | PSL_RI);
    192  1.85   aymeric 	if (platform.softintr_init != NULL)
    193  1.85   aymeric 		platform.softintr_init();
    194   1.1        ws }
    195   1.1        ws 
    196   1.1        ws void
    197   1.1        ws consinit()
    198   1.1        ws {
    199  1.29  sakamoto 
    200  1.78       chs 	(*cn_tab->cn_probe)(cn_tab);
    201  1.71   thorpej }
    202  1.71   thorpej 
    203  1.78       chs void	ofcons_cnprobe(struct consdev *);
    204  1.71   thorpej int	ofppc_cngetc(dev_t);
    205  1.71   thorpej void	ofppc_cnputc(dev_t, int);
    206  1.71   thorpej 
    207  1.71   thorpej struct consdev ofppc_bootcons = {
    208  1.78       chs 	ofcons_cnprobe, NULL, ofppc_cngetc, ofppc_cnputc, nullcnpollc, NULL,
    209  1.83     bjh21 	    NULL, NULL, makedev(0,0), 1,
    210  1.71   thorpej };
    211  1.71   thorpej 
    212  1.71   thorpej int	ofppc_stdin_ihandle, ofppc_stdout_ihandle;
    213  1.71   thorpej int	ofppc_stdin_phandle, ofppc_stdout_phandle;
    214  1.71   thorpej 
    215  1.71   thorpej void
    216  1.71   thorpej ofppc_bootstrap_console(void)
    217  1.71   thorpej {
    218  1.71   thorpej 	int chosen;
    219  1.71   thorpej 	char data[4];
    220  1.71   thorpej 
    221  1.71   thorpej 	chosen = OF_finddevice("/chosen");
    222  1.71   thorpej 
    223  1.71   thorpej 	if (OF_getprop(chosen, "stdin", data, sizeof(data)) != sizeof(int))
    224  1.71   thorpej 		goto nocons;
    225  1.71   thorpej 	ofppc_stdin_ihandle = of_decode_int(data);
    226  1.71   thorpej 	ofppc_stdin_phandle = OF_instance_to_package(ofppc_stdin_ihandle);
    227  1.71   thorpej 
    228  1.71   thorpej 	if (OF_getprop(chosen, "stdout", data, sizeof(data)) != sizeof(int))
    229  1.71   thorpej 		goto nocons;
    230  1.71   thorpej 	ofppc_stdout_ihandle = of_decode_int(data);
    231  1.71   thorpej 	ofppc_stdout_phandle = OF_instance_to_package(ofppc_stdout_ihandle);
    232  1.71   thorpej 
    233  1.71   thorpej 	cn_tab = &ofppc_bootcons;
    234  1.71   thorpej 
    235  1.71   thorpej  nocons:
    236  1.71   thorpej 	return;
    237  1.71   thorpej }
    238  1.71   thorpej 
    239  1.71   thorpej int
    240  1.71   thorpej ofppc_cngetc(dev_t dev)
    241  1.71   thorpej {
    242  1.71   thorpej 	u_char ch = '\0';
    243  1.71   thorpej 	int l;
    244  1.71   thorpej 
    245  1.71   thorpej 	while ((l = OF_read(ofppc_stdin_ihandle, &ch, 1)) != 1)
    246  1.71   thorpej 		if (l != -2 && l != 0)
    247  1.71   thorpej 			return (-1);
    248  1.71   thorpej 
    249  1.71   thorpej 	return (ch);
    250  1.71   thorpej }
    251  1.71   thorpej 
    252  1.71   thorpej void
    253  1.71   thorpej ofppc_cnputc(dev_t dev, int c)
    254  1.71   thorpej {
    255  1.71   thorpej 	char ch = c;
    256  1.71   thorpej 
    257  1.71   thorpej 	OF_write(ofppc_stdout_ihandle, &ch, 1);
    258   1.1        ws }
    259   1.1        ws 
    260   1.1        ws /*
    261   1.1        ws  * Crash dump handling.
    262   1.1        ws  */
    263   1.1        ws 
    264   1.1        ws /*
    265   1.1        ws  * Stray interrupts.
    266   1.1        ws  */
    267   1.1        ws void
    268   1.1        ws strayintr(irq)
    269   1.1        ws 	int irq;
    270   1.1        ws {
    271   1.1        ws 	log(LOG_ERR, "stray interrupt %d\n", irq);
    272   1.1        ws }
    273   1.1        ws 
    274   1.1        ws /*
    275   1.1        ws  * Halt or reboot the machine after syncing/dumping according to howto.
    276   1.1        ws  */
    277   1.1        ws void
    278   1.5       gwr cpu_reboot(howto, what)
    279   1.1        ws 	int howto;
    280   1.1        ws 	char *what;
    281   1.1        ws {
    282   1.1        ws 	static int syncing;
    283   1.1        ws 	static char str[256];
    284   1.1        ws 	char *ap = str, *ap1 = ap;
    285   1.1        ws 
    286   1.1        ws 	boothowto = howto;
    287   1.1        ws 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
    288   1.1        ws 		syncing = 1;
    289   1.1        ws 		vfs_shutdown();		/* sync */
    290   1.1        ws 		resettodr();		/* set wall clock */
    291   1.1        ws 	}
    292   1.1        ws 	splhigh();
    293   1.1        ws 	if (howto & RB_HALT) {
    294   1.1        ws 		doshutdownhooks();
    295   1.3  christos 		printf("halted\n\n");
    296   1.1        ws 		ppc_exit();
    297   1.1        ws 	}
    298   1.1        ws 	if (!cold && (howto & RB_DUMP))
    299  1.82      matt 		oea_dumpsys();
    300   1.1        ws 	doshutdownhooks();
    301   1.3  christos 	printf("rebooting\n\n");
    302   1.1        ws 	if (what && *what) {
    303   1.1        ws 		if (strlen(what) > sizeof str - 5)
    304   1.3  christos 			printf("boot string too large, ignored\n");
    305   1.1        ws 		else {
    306   1.1        ws 			strcpy(str, what);
    307   1.1        ws 			ap1 = ap = str + strlen(str);
    308   1.1        ws 			*ap++ = ' ';
    309   1.1        ws 		}
    310   1.1        ws 	}
    311   1.1        ws 	*ap++ = '-';
    312   1.1        ws 	if (howto & RB_SINGLE)
    313   1.1        ws 		*ap++ = 's';
    314   1.1        ws 	if (howto & RB_KDB)
    315   1.1        ws 		*ap++ = 'd';
    316   1.1        ws 	*ap++ = 0;
    317   1.1        ws 	if (ap[-2] == '-')
    318   1.1        ws 		*ap1 = 0;
    319   1.1        ws 	ppc_boot(str);
    320   1.1        ws }
    321   1.1        ws 
    322  1.68      matt #ifdef notyet
    323   1.1        ws /*
    324   1.1        ws  * OpenFirmware callback routine
    325   1.1        ws  */
    326   1.1        ws void
    327   1.1        ws callback(p)
    328   1.1        ws 	void *p;
    329   1.1        ws {
    330   1.1        ws 	panic("callback");	/* for now			XXX */
    331  1.60   thorpej }
    332  1.68      matt #endif
    333  1.60   thorpej 
    334  1.60   thorpej /*
    335  1.60   thorpej  * Perform an `splx()' for locore.
    336  1.60   thorpej  */
    337  1.60   thorpej int
    338  1.60   thorpej lcsplx(int ipl)
    339  1.60   thorpej {
    340  1.60   thorpej 
    341  1.73   thorpej 	return (_spllower(ipl));
    342   1.1        ws }
    343   1.1        ws 
    344   1.1        ws /*
    345   1.7   thorpej  * Initial Machine Interface.
    346   1.1        ws  */
    347   1.7   thorpej static int
    348  1.73   thorpej fake_spl(int new)
    349   1.7   thorpej {
    350   1.7   thorpej 	int scratch;
    351   1.7   thorpej 
    352   1.7   thorpej 	asm volatile ("mfmsr %0; andi. %0,%0,%1; mtmsr %0; isync"
    353   1.7   thorpej 	    : "=r"(scratch) : "K"((u_short)~(PSL_EE|PSL_ME)));
    354  1.29  sakamoto 	return (-1);
    355   1.7   thorpej }
    356   1.7   thorpej 
    357   1.1        ws static void
    358  1.73   thorpej fake_setsoft(int ipl)
    359   1.7   thorpej {
    360   1.7   thorpej 	/* Do nothing */
    361   1.7   thorpej }
    362   1.7   thorpej 
    363  1.73   thorpej static void
    364   1.1        ws fake_splx(new)
    365   1.1        ws 	int new;
    366   1.1        ws {
    367  1.73   thorpej 
    368  1.73   thorpej 	(void) fake_spl(0);
    369   1.7   thorpej }
    370   1.7   thorpej 
    371   1.7   thorpej static void
    372   1.7   thorpej fake_clock_return(frame, nticks)
    373   1.7   thorpej 	struct clockframe *frame;
    374   1.7   thorpej 	int nticks;
    375   1.7   thorpej {
    376   1.7   thorpej 	/* Do nothing */
    377   1.1        ws }
    378   1.1        ws 
    379  1.73   thorpej static void *
    380  1.73   thorpej fake_intr_establish(irq, level, ist, handler, arg)
    381  1.73   thorpej 	int irq, level, ist;
    382  1.73   thorpej 	int (*handler) __P((void *));
    383  1.73   thorpej 	void *arg;
    384  1.73   thorpej {
    385  1.73   thorpej 
    386  1.73   thorpej 	panic("fake_intr_establish");
    387  1.73   thorpej }
    388  1.73   thorpej 
    389   1.1        ws static void
    390  1.73   thorpej fake_intr_disestablish(cookie)
    391  1.73   thorpej 	void *cookie;
    392   1.1        ws {
    393  1.73   thorpej 
    394  1.73   thorpej 	panic("fake_intr_disestablish");
    395   1.1        ws }
    396