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