138465Smsmith/*-
238465Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
338465Smsmith * All rights reserved.
438465Smsmith *
538465Smsmith * Redistribution and use in source and binary forms, with or without
638465Smsmith * modification, are permitted provided that the following conditions
738465Smsmith * are met:
838465Smsmith * 1. Redistributions of source code must retain the above copyright
938465Smsmith *    notice, this list of conditions and the following disclaimer.
1038465Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1138465Smsmith *    notice, this list of conditions and the following disclaimer in the
1238465Smsmith *    documentation and/or other materials provided with the distribution.
1338465Smsmith *
1438465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1538465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1638465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1738465Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1838465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1938465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2038465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2138465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2238465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2338465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2438465Smsmith * SUCH DAMAGE.
2538465Smsmith */
2638465Smsmith
27119482Sobrien#include <sys/cdefs.h>
28119482Sobrien__FBSDID("$FreeBSD: releng/10.2/sys/boot/i386/libi386/bootinfo.c 271132 2014-09-04 20:47:14Z emaste $");
29119482Sobrien
3039902Smsmith#include <stand.h>
3139902Smsmith#include <sys/param.h>
3238465Smsmith#include <sys/reboot.h>
3340146Speter#include <sys/linker.h>
34271132Semaste#include <sys/boot.h>
3538465Smsmith#include "bootstrap.h"
3639902Smsmith#include "libi386.h"
3739902Smsmith#include "btxv86.h"
3838465Smsmith
3938465Smsmithint
4038465Smsmithbi_getboothowto(char *kargs)
4138465Smsmith{
4238465Smsmith    char	*cp;
43146698Sjhb    char	*curpos, *next, *string;
4438465Smsmith    int		howto;
4538465Smsmith    int		active;
4638465Smsmith    int		i;
47146698Sjhb    int		vidconsole;
48146698Sjhb
4939178Smsmith    /* Parse kargs */
5038465Smsmith    howto = 0;
5138465Smsmith    if (kargs  != NULL) {
5238465Smsmith	cp = kargs;
5338465Smsmith	active = 0;
5438465Smsmith	while (*cp != 0) {
5538465Smsmith	    if (!active && (*cp == '-')) {
5638465Smsmith		active = 1;
5738465Smsmith	    } else if (active)
5838465Smsmith		switch (*cp) {
5938465Smsmith		case 'a':
6038465Smsmith		    howto |= RB_ASKNAME;
6138465Smsmith		    break;
6247727Sghelmer		case 'C':
6347727Sghelmer		    howto |= RB_CDROM;
6447727Sghelmer		    break;
6538465Smsmith		case 'd':
6638465Smsmith		    howto |= RB_KDB;
6738465Smsmith		    break;
6885376Sjlemon		case 'D':
6985376Sjlemon		    howto |= RB_MULTIPLE;
7085376Sjlemon		    break;
7166133Sarchie		case 'm':
7266133Sarchie		    howto |= RB_MUTE;
7366133Sarchie		    break;
7438465Smsmith		case 'g':
7538465Smsmith		    howto |= RB_GDB;
7638465Smsmith		    break;
7738465Smsmith		case 'h':
7838465Smsmith		    howto |= RB_SERIAL;
7938465Smsmith		    break;
8087620Sguido		case 'p':
8187620Sguido		    howto |= RB_PAUSE;
8287620Sguido		    break;
8338465Smsmith		case 'r':
8438465Smsmith		    howto |= RB_DFLTROOT;
8538465Smsmith		    break;
8638465Smsmith		case 's':
8738465Smsmith		    howto |= RB_SINGLE;
8838465Smsmith		    break;
8938465Smsmith		case 'v':
9038465Smsmith		    howto |= RB_VERBOSE;
9138465Smsmith		    break;
9238465Smsmith		default:
9338465Smsmith		    active = 0;
9438465Smsmith		    break;
9538465Smsmith		}
9639178Smsmith	    cp++;
9738465Smsmith	}
9838465Smsmith    }
9939178Smsmith    /* get equivalents from the environment */
10038465Smsmith    for (i = 0; howto_names[i].ev != NULL; i++)
10138465Smsmith	if (getenv(howto_names[i].ev) != NULL)
10238465Smsmith	    howto |= howto_names[i].mask;
103146698Sjhb
104146698Sjhb    /* Enable selected consoles */
105146698Sjhb    string = next = strdup(getenv("console"));
106146698Sjhb    vidconsole = 0;
107146698Sjhb    while (next != NULL) {
108146698Sjhb	curpos = strsep(&next, " ,");
109146698Sjhb	if (*curpos == '\0')
110146698Sjhb		continue;
111146698Sjhb	if (!strcmp(curpos, "vidconsole"))
112146698Sjhb	    vidconsole = 1;
113146698Sjhb	else if (!strcmp(curpos, "comconsole"))
114146698Sjhb	    howto |= RB_SERIAL;
115146698Sjhb	else if (!strcmp(curpos, "nullconsole"))
116146698Sjhb	    howto |= RB_MUTE;
117146698Sjhb    }
118146698Sjhb
119146698Sjhb    if (vidconsole && (howto & RB_SERIAL))
120146698Sjhb	howto |= RB_MULTIPLE;
121146698Sjhb
122146698Sjhb    /*
123146698Sjhb     * XXX: Note that until the kernel is ready to respect multiple consoles
124146698Sjhb     * for the boot messages, the first named console is the primary console
125146698Sjhb     */
126146698Sjhb    if (!strcmp(string, "vidconsole"))
127146698Sjhb	howto &= ~RB_SERIAL;
128146698Sjhb
129146698Sjhb    free(string);
130146698Sjhb
13138465Smsmith    return(howto);
13238465Smsmith}
13338465Smsmith
134150470Sruvoid
135150470Srubi_setboothowto(int howto)
136150470Sru{
137150470Sru    int		i;
138150470Sru
139150470Sru    for (i = 0; howto_names[i].ev != NULL; i++)
140150470Sru	if (howto & howto_names[i].mask)
141150470Sru	    setenv(howto_names[i].ev, "YES", 1);
142150470Sru}
143150470Sru
14438465Smsmith/*
14538465Smsmith * Copy the environment into the load area starting at (addr).
14638465Smsmith * Each variable is formatted as <name>=<value>, with a single nul
14738465Smsmith * separating each variable, and a double nul terminating the environment.
14838465Smsmith */
14938465Smsmithvm_offset_t
15038465Smsmithbi_copyenv(vm_offset_t addr)
15138465Smsmith{
15238465Smsmith    struct env_var	*ep;
15338465Smsmith
15438465Smsmith    /* traverse the environment */
15538465Smsmith    for (ep = environ; ep != NULL; ep = ep->ev_next) {
15639441Smsmith	i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
15738465Smsmith	addr += strlen(ep->ev_name);
15839441Smsmith	i386_copyin("=", addr, 1);
15938465Smsmith	addr++;
16038465Smsmith	if (ep->ev_value != NULL) {
16139441Smsmith	    i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
16238465Smsmith	    addr += strlen(ep->ev_value);
16338465Smsmith	}
16439441Smsmith	i386_copyin("", addr, 1);
16538465Smsmith	addr++;
16638465Smsmith    }
16739441Smsmith    i386_copyin("", addr, 1);
16838465Smsmith    addr++;
16939730Speter    return(addr);
17038465Smsmith}
171