xref: /onnv-gate/usr/src/psm/stand/boot/sparc/common/bootflags.c (revision 5648:161f8007cab9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*5648Ssetje  * Common Development and Distribution License (the "License").
6*5648Ssetje  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*5648Ssetje  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/types.h>
290Sstevel@tonic-gate #include <sys/bootconf.h>
300Sstevel@tonic-gate #include <sys/reboot.h>
310Sstevel@tonic-gate #include <sys/param.h>
320Sstevel@tonic-gate #include <sys/salib.h>
330Sstevel@tonic-gate #include <sys/debug.h>
340Sstevel@tonic-gate #include <sys/promif.h>
350Sstevel@tonic-gate #include <sys/boot.h>
360Sstevel@tonic-gate #include <sys/sysmacros.h>
370Sstevel@tonic-gate #include <util/getoptstr.h>
380Sstevel@tonic-gate #include "boot_plat.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate static char default_path_buf[MAXPATHLEN];
410Sstevel@tonic-gate 
420Sstevel@tonic-gate char	wanboot_arguments[OBP_MAXPATHLEN];	/* args following "-o" */
430Sstevel@tonic-gate 
44*5648Ssetje char	cmd_line_boot_archive[MAXPATHLEN];
45*5648Ssetje 
46*5648Ssetje boolean_t	halt;
47*5648Ssetje 
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate  * Parse the boot arguments, adding the options found to the existing boothowto
500Sstevel@tonic-gate  * value (if any) or other state.  Then rewrite the buffer with arguments for
510Sstevel@tonic-gate  * the standalone.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * NOTE: boothowto may already have bits set when this function is called
540Sstevel@tonic-gate  */
550Sstevel@tonic-gate void
bootflags(char * args,size_t argsz)560Sstevel@tonic-gate bootflags(char *args, size_t argsz)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate 	static char newargs[OBP_MAXPATHLEN];
590Sstevel@tonic-gate 	struct gos_params params;
600Sstevel@tonic-gate 	const char *cp;
610Sstevel@tonic-gate 	char *np;
620Sstevel@tonic-gate 	size_t npres;
630Sstevel@tonic-gate 	int c;
64*5648Ssetje 	char *cmd_line_default_path;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	cmd_line_default_path = NULL;
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	params.gos_opts = "HXF:VnI:D:advhko:";
690Sstevel@tonic-gate 	params.gos_strp = args;
700Sstevel@tonic-gate 	getoptstr_init(&params);
710Sstevel@tonic-gate 	while ((c = getoptstr(&params)) != -1) {
720Sstevel@tonic-gate 		switch (c) {
730Sstevel@tonic-gate 		/*
74*5648Ssetje 		 * Bootblock flags.
750Sstevel@tonic-gate 		 */
760Sstevel@tonic-gate 		case 'H':
77*5648Ssetje 			halt = B_TRUE;
78*5648Ssetje 			/*FALLTHRU*/
790Sstevel@tonic-gate 		case 'X':
80*5648Ssetje 			break;
81*5648Ssetje 
820Sstevel@tonic-gate 		case 'F':
83*5648Ssetje 			if (params.gos_optarglen >=
84*5648Ssetje 			    sizeof (cmd_line_boot_archive)) {
85*5648Ssetje 				printf("boot: -F argument too long.  "
86*5648Ssetje 				    "Ignoring.\n");
87*5648Ssetje 				break;
88*5648Ssetje 			}
89*5648Ssetje 			(void) strncpy(cmd_line_boot_archive,
90*5648Ssetje 			    params.gos_optargp, params.gos_optarglen);
91*5648Ssetje 			cmd_line_boot_archive[params.gos_optarglen] = '\0';
920Sstevel@tonic-gate 			break;
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 		/*
950Sstevel@tonic-gate 		 * Boot flags.
960Sstevel@tonic-gate 		 */
970Sstevel@tonic-gate 		case 'V':
980Sstevel@tonic-gate 			verbosemode = 1;
990Sstevel@tonic-gate 			break;
1000Sstevel@tonic-gate 		case 'n':
1010Sstevel@tonic-gate 			cache_state = 0;
1020Sstevel@tonic-gate 			printf("Warning: boot will not enable cache\n");
1030Sstevel@tonic-gate 			break;
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 		case 'D':
1060Sstevel@tonic-gate 			if (params.gos_optarglen >= sizeof (default_path_buf)) {
1070Sstevel@tonic-gate 				printf("boot: -D argument too long.  "
1080Sstevel@tonic-gate 				    "Ignoring.\n");
1090Sstevel@tonic-gate 				break;
1100Sstevel@tonic-gate 			}
1110Sstevel@tonic-gate 			(void) strncpy(default_path_buf, params.gos_optargp,
1120Sstevel@tonic-gate 			    params.gos_optarglen);
1130Sstevel@tonic-gate 			default_path_buf[params.gos_optarglen] = '\0';
1140Sstevel@tonic-gate 			cmd_line_default_path = default_path_buf;
1150Sstevel@tonic-gate 			break;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 		case 'o':
1180Sstevel@tonic-gate 			if (params.gos_optarglen >=
1190Sstevel@tonic-gate 			    sizeof (wanboot_arguments)) {
1200Sstevel@tonic-gate 				printf("boot: -o argument too long.  "
1210Sstevel@tonic-gate 				    "Ignoring.\n");
1220Sstevel@tonic-gate 				break;
1230Sstevel@tonic-gate 			}
1240Sstevel@tonic-gate 			(void) strncpy(wanboot_arguments, params.gos_optargp,
1250Sstevel@tonic-gate 			    params.gos_optarglen);
1260Sstevel@tonic-gate 			wanboot_arguments[params.gos_optarglen] = '\0';
1270Sstevel@tonic-gate 			break;
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 		case 'a':
1300Sstevel@tonic-gate 			boothowto |= RB_ASKNAME;
1310Sstevel@tonic-gate 			break;
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 		case 'd':
1340Sstevel@tonic-gate 			boothowto |= RB_DEBUGENTER;
1350Sstevel@tonic-gate 			break;
1360Sstevel@tonic-gate 		case 'v':
1370Sstevel@tonic-gate 			boothowto |= RB_VERBOSE;
1380Sstevel@tonic-gate 			break;
1390Sstevel@tonic-gate 		case 'h':
1400Sstevel@tonic-gate 			boothowto |= RB_HALT;
1410Sstevel@tonic-gate 			break;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 		/* Consumed by the kernel */
1440Sstevel@tonic-gate 		case 'k':
1450Sstevel@tonic-gate 			boothowto |= RB_KMDB;
1460Sstevel@tonic-gate 			break;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 		/*
1490Sstevel@tonic-gate 		 * Unrecognized flags: stop.
1500Sstevel@tonic-gate 		 */
1510Sstevel@tonic-gate 		case '?':
1520Sstevel@tonic-gate 			/*
1530Sstevel@tonic-gate 			 * Error.  Either an unrecognized option, or an option
1540Sstevel@tonic-gate 			 * without an argument.  Check for the latter.
1550Sstevel@tonic-gate 			 */
1560Sstevel@tonic-gate 			switch (params.gos_last_opt) {
1570Sstevel@tonic-gate 			case 'F':
1580Sstevel@tonic-gate 			case 'I':
1590Sstevel@tonic-gate 			case 'D':
1600Sstevel@tonic-gate 			case 'o':
1610Sstevel@tonic-gate 				printf("boot: -%c flag missing required "
1620Sstevel@tonic-gate 				    "argument.  Ignoring.\n",
1630Sstevel@tonic-gate 				    params.gos_last_opt);
1640Sstevel@tonic-gate 				break;
1650Sstevel@tonic-gate 			default:
1660Sstevel@tonic-gate 				/* Unrecognized option.  Stop. */
1670Sstevel@tonic-gate 				goto done;
1680Sstevel@tonic-gate 			}
1690Sstevel@tonic-gate 			break;
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 		default:
1720Sstevel@tonic-gate 			printf("boot: Ignoring unimplemented option -%c.\n", c);
1730Sstevel@tonic-gate 		}
1740Sstevel@tonic-gate 	}
1750Sstevel@tonic-gate done:
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	/*
1780Sstevel@tonic-gate 	 * Construct the arguments for the standalone.
1790Sstevel@tonic-gate 	 */
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	*newargs = '\0';
1820Sstevel@tonic-gate 	np = newargs;
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	/*
1850Sstevel@tonic-gate 	 * We need a dash if we encountered an unrecognized option or if we
1860Sstevel@tonic-gate 	 * need to pass flags on.
1870Sstevel@tonic-gate 	 */
1880Sstevel@tonic-gate 	if (c == '?' || (boothowto &
1890Sstevel@tonic-gate 	    /* These flags are to be passed to the standalone. */
1900Sstevel@tonic-gate 	    (RB_ASKNAME | RB_DEBUGENTER | RB_VERBOSE | RB_HALT | RB_KMDB))) {
1910Sstevel@tonic-gate 		*np++ = '-';
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 		/*
1940Sstevel@tonic-gate 		 * boot(1M) says to pass these on.
1950Sstevel@tonic-gate 		 */
1960Sstevel@tonic-gate 		if (boothowto & RB_ASKNAME)
1970Sstevel@tonic-gate 			*np++ = 'a';
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 		/*
2000Sstevel@tonic-gate 		 * boot isn't documented as consuming these flags, so pass
2010Sstevel@tonic-gate 		 * them on.
2020Sstevel@tonic-gate 		 */
2030Sstevel@tonic-gate 		if (boothowto & RB_DEBUGENTER)
2040Sstevel@tonic-gate 			*np++ = 'd';
2050Sstevel@tonic-gate 		if (boothowto & RB_KMDB)
2060Sstevel@tonic-gate 			*np++ = 'k';
2070Sstevel@tonic-gate 		if (boothowto & RB_VERBOSE)
2080Sstevel@tonic-gate 			*np++ = 'v';
2090Sstevel@tonic-gate 		if (boothowto & RB_HALT)
2100Sstevel@tonic-gate 			*np++ = 'h';
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 		/*
2130Sstevel@tonic-gate 		 * If we didn't encounter an unrecognized flag and there's
2140Sstevel@tonic-gate 		 * more to copy, add a space to separate these flags.
2150Sstevel@tonic-gate 		 * (Otherwise, unrecognized flags can be appended since we
2160Sstevel@tonic-gate 		 * started this word with a dash.)
2170Sstevel@tonic-gate 		 */
2180Sstevel@tonic-gate 		if (c == -1 && params.gos_strp[0] != '\0')
2190Sstevel@tonic-gate 			*np++ = ' ';
2200Sstevel@tonic-gate 	}
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	npres = sizeof (newargs) - (size_t)(np - newargs);
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	if (c == '?') {
2250Sstevel@tonic-gate 		/*
2260Sstevel@tonic-gate 		 * Unrecognized flag: Copy gos_errp to end of line or a "--"
2270Sstevel@tonic-gate 		 * word.
2280Sstevel@tonic-gate 		 */
2290Sstevel@tonic-gate 		cp = params.gos_errp;
2300Sstevel@tonic-gate 		while (*cp && npres > 0) {
2310Sstevel@tonic-gate 			if (cp[0] == '-' && cp[1] == '-' &&
2320Sstevel@tonic-gate 			    (cp[2] == '\0' || ISSPACE(cp[2]))) {
2330Sstevel@tonic-gate 				cp += 2;
2340Sstevel@tonic-gate 				SKIP_SPC(cp);
2350Sstevel@tonic-gate 				break;
2360Sstevel@tonic-gate 			} else {
2370Sstevel@tonic-gate 				const char *sp = cp;
2380Sstevel@tonic-gate 				size_t sz;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 				/* Copy until the next word. */
2410Sstevel@tonic-gate 				while (*cp && !ISSPACE(*cp))
2420Sstevel@tonic-gate 					cp++;
2430Sstevel@tonic-gate 				while (ISSPACE(*cp))
2440Sstevel@tonic-gate 					cp++;
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 				sz = MIN(npres, (size_t)(cp - sp));
2470Sstevel@tonic-gate 				npres -= sz;
2480Sstevel@tonic-gate 				bcopy(sp, np, sz);
2490Sstevel@tonic-gate 				np += sz;
2500Sstevel@tonic-gate 			}
2510Sstevel@tonic-gate 		}
2520Sstevel@tonic-gate 	} else {
2530Sstevel@tonic-gate 		cp = params.gos_strp;
2540Sstevel@tonic-gate 	}
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	while (npres > 0 && (*np++ = *cp++) != '\0')
2570Sstevel@tonic-gate 		npres--;
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	newargs[sizeof (newargs) - 1] = '\0';
2600Sstevel@tonic-gate 	(void) strlcpy(args, newargs, argsz);
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	/*
2630Sstevel@tonic-gate 	 * If a default filename was specified in the args, set it.
2640Sstevel@tonic-gate 	 */
2650Sstevel@tonic-gate 	if (cmd_line_default_path)
2660Sstevel@tonic-gate 		set_default_filename(cmd_line_default_path);
267*5648Ssetje 
268*5648Ssetje 	/*
269*5648Ssetje 	 * See if user wants to examine things
270*5648Ssetje 	 */
271*5648Ssetje 	if (halt == B_TRUE)
272*5648Ssetje 		prom_enter_mon();
2730Sstevel@tonic-gate }
274