Home | History | Annotate | Line # | Download | only in ofppc
machdep.c revision 1.76
      1  1.76      matt /*	$NetBSD: machdep.c,v 1.76 2002/07/05 18:45:19 matt 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.21  jonathan 
     34  1.27   thorpej #include "opt_compat_netbsd.h"
     35  1.21  jonathan #include "opt_ddb.h"
     36   1.1        ws 
     37   1.1        ws #include <sys/param.h>
     38   1.1        ws #include <sys/buf.h>
     39   1.1        ws #include <sys/exec.h>
     40   1.1        ws #include <sys/malloc.h>
     41   1.1        ws #include <sys/map.h>
     42   1.1        ws #include <sys/mbuf.h>
     43   1.1        ws #include <sys/mount.h>
     44   1.1        ws #include <sys/msgbuf.h>
     45   1.1        ws #include <sys/proc.h>
     46   1.1        ws #include <sys/reboot.h>
     47   1.1        ws #include <sys/syscallargs.h>
     48   1.1        ws #include <sys/syslog.h>
     49   1.1        ws #include <sys/systm.h>
     50  1.43   thorpej #include <sys/kernel.h>
     51   1.1        ws #include <sys/user.h>
     52  1.59  jdolecek #include <sys/boot_flag.h>
     53   1.1        ws 
     54  1.19  sakamoto #include <uvm/uvm_extern.h>
     55  1.19  sakamoto 
     56   1.1        ws #include <net/netisr.h>
     57   1.1        ws 
     58  1.72   thorpej #include <machine/db_machdep.h>
     59  1.72   thorpej #include <ddb/db_extern.h>
     60  1.72   thorpej 
     61  1.70   thorpej #include <dev/ofw/openfirm.h>
     62  1.70   thorpej 
     63  1.68      matt #include <machine/autoconf.h>
     64   1.1        ws #include <machine/bat.h>
     65   1.1        ws #include <machine/pmap.h>
     66   1.1        ws #include <machine/powerpc.h>
     67   1.1        ws #include <machine/trap.h>
     68  1.54   thorpej 
     69  1.71   thorpej #include <machine/platform.h>
     70  1.71   thorpej 
     71  1.68      matt #include <dev/cons.h>
     72   1.1        ws 
     73   1.1        ws /*
     74   1.1        ws  * Global variables used here and there
     75   1.1        ws  */
     76   1.1        ws char *bootpath;
     77   1.1        ws 
     78  1.76      matt int lcsplx(int);			/* called from locore.S */
     79  1.60   thorpej 
     80  1.73   thorpej static int fake_spl __P((int));
     81  1.73   thorpej static void fake_splx __P((int));
     82  1.73   thorpej static void fake_setsoft __P((int));
     83   1.7   thorpej static void fake_clock_return __P((struct clockframe *, int));
     84  1.73   thorpej static void *fake_intr_establish __P((int, int, int, int (*)(void *), void *));
     85  1.73   thorpej static void fake_intr_disestablish __P((void *));
     86   1.1        ws 
     87   1.1        ws struct machvec machine_interface = {
     88  1.44  wrstuden 	fake_spl,
     89   1.7   thorpej 	fake_spl,
     90   1.1        ws 	fake_splx,
     91   1.7   thorpej 	fake_setsoft,
     92   1.7   thorpej 	fake_clock_return,
     93  1.73   thorpej 	fake_intr_establish,
     94  1.73   thorpej 	fake_intr_disestablish,
     95   1.1        ws };
     96   1.1        ws 
     97  1.71   thorpej void	ofppc_bootstrap_console(void);
     98  1.70   thorpej 
     99   1.1        ws void
    100   1.1        ws initppc(startkernel, endkernel, args)
    101   1.1        ws 	u_int startkernel, endkernel;
    102   1.1        ws 	char *args;
    103   1.1        ws {
    104  1.14  sakamoto #ifdef DDB
    105  1.72   thorpej 	extern void *startsym, *endsym;
    106  1.14  sakamoto #endif
    107   1.1        ws 
    108  1.71   thorpej 	/* Initialize the bootstrap console. */
    109  1.71   thorpej 	ofppc_bootstrap_console();
    110  1.71   thorpej 
    111   1.1        ws 	/*
    112  1.76      matt 	 * Initialize the bat registers
    113   1.1        ws 	 */
    114  1.76      matt 	mpc6xx_batinit(0);
    115  1.29  sakamoto 
    116   1.1        ws 	/*
    117  1.73   thorpej 	 * Initialize the platform structure.  This may add entries
    118  1.73   thorpej 	 * to the BAT table.
    119  1.73   thorpej 	 */
    120  1.73   thorpej 	platform_init();
    121  1.73   thorpej 
    122  1.73   thorpej #ifdef __notyet__	/* Needs some rethinking regarding real/virtual OFW */
    123  1.73   thorpej 	OF_set_callback(callback);
    124  1.73   thorpej #endif
    125  1.73   thorpej 
    126  1.76      matt 	mpc6xx_init(NULL);
    127   1.1        ws 
    128   1.1        ws 	/*
    129  1.73   thorpej 	 * Now that translation is enabled (and we can access bus space),
    130  1.73   thorpej 	 * initialize the console.
    131  1.73   thorpej 	 */
    132  1.73   thorpej 	(*platform.cons_init)();
    133  1.73   thorpej 
    134  1.73   thorpej 	/*
    135   1.1        ws 	 * Parse arg string.
    136   1.1        ws 	 */
    137   1.1        ws 	bootpath = args;
    138   1.7   thorpej 	while (*++args && *args != ' ');
    139   1.1        ws 	if (*args) {
    140  1.59  jdolecek 		for(*args++ = 0; *args; args++)
    141  1.59  jdolecek 			BOOT_FLAG(*args, boothowto);
    142  1.29  sakamoto 	}
    143   1.1        ws 
    144  1.72   thorpej 	/*
    145  1.72   thorpej 	 * Set the page size.
    146  1.72   thorpej 	 */
    147  1.72   thorpej 	uvm_setpagesize();
    148  1.72   thorpej 
    149  1.72   thorpej 	/*
    150  1.72   thorpej 	 * Initialize pmap module.
    151  1.72   thorpej 	 */
    152  1.74    kleink 	pmap_bootstrap(startkernel, endkernel, NULL);
    153  1.72   thorpej 
    154  1.14  sakamoto #ifdef DDB
    155  1.72   thorpej 	ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
    156  1.72   thorpej 	if (boothowto & RB_KDB)
    157  1.72   thorpej 		Debugger();
    158  1.14  sakamoto #endif
    159  1.53        ws #ifdef IPKDB
    160   1.1        ws 	/*
    161   1.4        ws 	 * Now trap to IPKDB
    162   1.1        ws 	 */
    163   1.4        ws 	ipkdb_init();
    164   1.1        ws 	if (boothowto & RB_KDB)
    165   1.4        ws 		ipkdb_connect(0);
    166   1.1        ws #endif
    167   1.1        ws }
    168   1.1        ws 
    169   1.1        ws /*
    170   1.1        ws  * Machine dependent startup code.
    171   1.1        ws  */
    172   1.1        ws void
    173   1.1        ws cpu_startup()
    174   1.1        ws {
    175  1.76      matt 	int msr;
    176  1.76      matt 	mpc6xx_startup(NULL);
    177   1.1        ws 
    178   1.1        ws 	/*
    179   1.1        ws 	 * Now allow hardware interrupts.
    180   1.1        ws 	 */
    181  1.76      matt 	splhigh();
    182  1.76      matt 	asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
    183  1.76      matt 	    :	"=r"(msr)
    184  1.76      matt 	    :	"K"((u_short)(PSL_EE|PSL_RI)));
    185   1.1        ws }
    186   1.1        ws 
    187   1.1        ws void
    188   1.1        ws consinit()
    189   1.1        ws {
    190  1.29  sakamoto 
    191  1.71   thorpej 	/* Nothing to do; console is already initialized. */
    192  1.71   thorpej }
    193  1.71   thorpej 
    194  1.71   thorpej int	ofppc_cngetc(dev_t);
    195  1.71   thorpej void	ofppc_cnputc(dev_t, int);
    196  1.71   thorpej 
    197  1.71   thorpej struct consdev ofppc_bootcons = {
    198  1.71   thorpej 	NULL, NULL, ofppc_cngetc, ofppc_cnputc, nullcnpollc, NULL,
    199  1.71   thorpej 	    makedev(0,0), 1,
    200  1.71   thorpej };
    201  1.71   thorpej 
    202  1.71   thorpej int	ofppc_stdin_ihandle, ofppc_stdout_ihandle;
    203  1.71   thorpej int	ofppc_stdin_phandle, ofppc_stdout_phandle;
    204  1.71   thorpej 
    205  1.71   thorpej void
    206  1.71   thorpej ofppc_bootstrap_console(void)
    207  1.71   thorpej {
    208  1.71   thorpej 	int chosen;
    209  1.71   thorpej 	char data[4];
    210  1.71   thorpej 
    211  1.71   thorpej 	chosen = OF_finddevice("/chosen");
    212  1.71   thorpej 
    213  1.71   thorpej 	if (OF_getprop(chosen, "stdin", data, sizeof(data)) != sizeof(int))
    214  1.71   thorpej 		goto nocons;
    215  1.71   thorpej 	ofppc_stdin_ihandle = of_decode_int(data);
    216  1.71   thorpej 	ofppc_stdin_phandle = OF_instance_to_package(ofppc_stdin_ihandle);
    217  1.71   thorpej 
    218  1.71   thorpej 	if (OF_getprop(chosen, "stdout", data, sizeof(data)) != sizeof(int))
    219  1.71   thorpej 		goto nocons;
    220  1.71   thorpej 	ofppc_stdout_ihandle = of_decode_int(data);
    221  1.71   thorpej 	ofppc_stdout_phandle = OF_instance_to_package(ofppc_stdout_ihandle);
    222  1.71   thorpej 
    223  1.71   thorpej 	cn_tab = &ofppc_bootcons;
    224  1.71   thorpej 
    225  1.71   thorpej  nocons:
    226  1.71   thorpej 	return;
    227  1.71   thorpej }
    228  1.71   thorpej 
    229  1.71   thorpej int
    230  1.71   thorpej ofppc_cngetc(dev_t dev)
    231  1.71   thorpej {
    232  1.71   thorpej 	u_char ch = '\0';
    233  1.71   thorpej 	int l;
    234  1.71   thorpej 
    235  1.71   thorpej 	while ((l = OF_read(ofppc_stdin_ihandle, &ch, 1)) != 1)
    236  1.71   thorpej 		if (l != -2 && l != 0)
    237  1.71   thorpej 			return (-1);
    238  1.71   thorpej 
    239  1.71   thorpej 	return (ch);
    240  1.71   thorpej }
    241  1.71   thorpej 
    242  1.71   thorpej void
    243  1.71   thorpej ofppc_cnputc(dev_t dev, int c)
    244  1.71   thorpej {
    245  1.71   thorpej 	char ch = c;
    246  1.71   thorpej 
    247  1.71   thorpej 	OF_write(ofppc_stdout_ihandle, &ch, 1);
    248   1.1        ws }
    249   1.1        ws 
    250   1.1        ws /*
    251   1.1        ws  * Crash dump handling.
    252   1.1        ws  */
    253   1.1        ws 
    254   1.1        ws /*
    255   1.1        ws  * Stray interrupts.
    256   1.1        ws  */
    257   1.1        ws void
    258   1.1        ws strayintr(irq)
    259   1.1        ws 	int irq;
    260   1.1        ws {
    261   1.1        ws 	log(LOG_ERR, "stray interrupt %d\n", irq);
    262   1.1        ws }
    263   1.1        ws 
    264   1.1        ws /*
    265   1.1        ws  * Halt or reboot the machine after syncing/dumping according to howto.
    266   1.1        ws  */
    267   1.1        ws void
    268   1.5       gwr cpu_reboot(howto, what)
    269   1.1        ws 	int howto;
    270   1.1        ws 	char *what;
    271   1.1        ws {
    272   1.1        ws 	static int syncing;
    273   1.1        ws 	static char str[256];
    274   1.1        ws 	char *ap = str, *ap1 = ap;
    275   1.1        ws 
    276   1.1        ws 	boothowto = howto;
    277   1.1        ws 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
    278   1.1        ws 		syncing = 1;
    279   1.1        ws 		vfs_shutdown();		/* sync */
    280   1.1        ws 		resettodr();		/* set wall clock */
    281   1.1        ws 	}
    282   1.1        ws 	splhigh();
    283   1.1        ws 	if (howto & RB_HALT) {
    284   1.1        ws 		doshutdownhooks();
    285   1.3  christos 		printf("halted\n\n");
    286   1.1        ws 		ppc_exit();
    287   1.1        ws 	}
    288   1.1        ws 	if (!cold && (howto & RB_DUMP))
    289  1.76      matt 		mpc6xx_dumpsys();
    290   1.1        ws 	doshutdownhooks();
    291   1.3  christos 	printf("rebooting\n\n");
    292   1.1        ws 	if (what && *what) {
    293   1.1        ws 		if (strlen(what) > sizeof str - 5)
    294   1.3  christos 			printf("boot string too large, ignored\n");
    295   1.1        ws 		else {
    296   1.1        ws 			strcpy(str, what);
    297   1.1        ws 			ap1 = ap = str + strlen(str);
    298   1.1        ws 			*ap++ = ' ';
    299   1.1        ws 		}
    300   1.1        ws 	}
    301   1.1        ws 	*ap++ = '-';
    302   1.1        ws 	if (howto & RB_SINGLE)
    303   1.1        ws 		*ap++ = 's';
    304   1.1        ws 	if (howto & RB_KDB)
    305   1.1        ws 		*ap++ = 'd';
    306   1.1        ws 	*ap++ = 0;
    307   1.1        ws 	if (ap[-2] == '-')
    308   1.1        ws 		*ap1 = 0;
    309   1.1        ws 	ppc_boot(str);
    310   1.1        ws }
    311   1.1        ws 
    312  1.68      matt #ifdef notyet
    313   1.1        ws /*
    314   1.1        ws  * OpenFirmware callback routine
    315   1.1        ws  */
    316   1.1        ws void
    317   1.1        ws callback(p)
    318   1.1        ws 	void *p;
    319   1.1        ws {
    320   1.1        ws 	panic("callback");	/* for now			XXX */
    321  1.60   thorpej }
    322  1.68      matt #endif
    323  1.60   thorpej 
    324  1.60   thorpej /*
    325  1.60   thorpej  * Perform an `splx()' for locore.
    326  1.60   thorpej  */
    327  1.60   thorpej int
    328  1.60   thorpej lcsplx(int ipl)
    329  1.60   thorpej {
    330  1.60   thorpej 
    331  1.73   thorpej 	return (_spllower(ipl));
    332   1.1        ws }
    333   1.1        ws 
    334   1.1        ws /*
    335   1.7   thorpej  * Initial Machine Interface.
    336   1.1        ws  */
    337   1.7   thorpej static int
    338  1.73   thorpej fake_spl(int new)
    339   1.7   thorpej {
    340   1.7   thorpej 	int scratch;
    341   1.7   thorpej 
    342   1.7   thorpej 	asm volatile ("mfmsr %0; andi. %0,%0,%1; mtmsr %0; isync"
    343   1.7   thorpej 	    : "=r"(scratch) : "K"((u_short)~(PSL_EE|PSL_ME)));
    344  1.29  sakamoto 	return (-1);
    345   1.7   thorpej }
    346   1.7   thorpej 
    347   1.1        ws static void
    348  1.73   thorpej fake_setsoft(int ipl)
    349   1.7   thorpej {
    350   1.7   thorpej 	/* Do nothing */
    351   1.7   thorpej }
    352   1.7   thorpej 
    353  1.73   thorpej static void
    354   1.1        ws fake_splx(new)
    355   1.1        ws 	int new;
    356   1.1        ws {
    357  1.73   thorpej 
    358  1.73   thorpej 	(void) fake_spl(0);
    359   1.7   thorpej }
    360   1.7   thorpej 
    361   1.7   thorpej static void
    362   1.7   thorpej fake_clock_return(frame, nticks)
    363   1.7   thorpej 	struct clockframe *frame;
    364   1.7   thorpej 	int nticks;
    365   1.7   thorpej {
    366   1.7   thorpej 	/* Do nothing */
    367   1.1        ws }
    368   1.1        ws 
    369  1.73   thorpej static void *
    370  1.73   thorpej fake_intr_establish(irq, level, ist, handler, arg)
    371  1.73   thorpej 	int irq, level, ist;
    372  1.73   thorpej 	int (*handler) __P((void *));
    373  1.73   thorpej 	void *arg;
    374  1.73   thorpej {
    375  1.73   thorpej 
    376  1.73   thorpej 	panic("fake_intr_establish");
    377  1.73   thorpej }
    378  1.73   thorpej 
    379   1.1        ws static void
    380  1.73   thorpej fake_intr_disestablish(cookie)
    381  1.73   thorpej 	void *cookie;
    382   1.1        ws {
    383  1.73   thorpej 
    384  1.73   thorpej 	panic("fake_intr_disestablish");
    385   1.1        ws }
    386