 f4ed2877b1
			
		
	
	
	f4ed2877b1
	
	
	
		
			
			Separate early_serial_console from tty.c
This allows for reuse of
early_serial_console.c/string.c/printf.c/cmdline.c in boot/compressed/.
-v2: according to hpa, don't include string.c etc
-v3: compressed/misc.c must have early_serial_base as static, so move it back to tty.c
     for setup code
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <4C568D2B.205@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
		
	
			
		
			
				
	
	
		
			158 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /* -*- linux-c -*- ------------------------------------------------------- *
 | |
|  *
 | |
|  *   Copyright (C) 1991, 1992 Linus Torvalds
 | |
|  *   Copyright 2007 rPath, Inc. - All Rights Reserved
 | |
|  *
 | |
|  *   This file is part of the Linux kernel, and is made available under
 | |
|  *   the terms of the GNU General Public License version 2.
 | |
|  *
 | |
|  * ----------------------------------------------------------------------- */
 | |
| 
 | |
| /*
 | |
|  * Simple command-line parser for early boot.
 | |
|  */
 | |
| 
 | |
| #include "boot.h"
 | |
| 
 | |
| static inline int myisspace(u8 c)
 | |
| {
 | |
| 	return c <= ' ';	/* Close enough approximation */
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Find a non-boolean option, that is, "option=argument".  In accordance
 | |
|  * with standard Linux practice, if this option is repeated, this returns
 | |
|  * the last instance on the command line.
 | |
|  *
 | |
|  * Returns the length of the argument (regardless of if it was
 | |
|  * truncated to fit in the buffer), or -1 on not found.
 | |
|  */
 | |
| int __cmdline_find_option(u32 cmdline_ptr, const char *option, char *buffer, int bufsize)
 | |
| {
 | |
| 	addr_t cptr;
 | |
| 	char c;
 | |
| 	int len = -1;
 | |
| 	const char *opptr = NULL;
 | |
| 	char *bufptr = buffer;
 | |
| 	enum {
 | |
| 		st_wordstart,	/* Start of word/after whitespace */
 | |
| 		st_wordcmp,	/* Comparing this word */
 | |
| 		st_wordskip,	/* Miscompare, skip */
 | |
| 		st_bufcpy	/* Copying this to buffer */
 | |
| 	} state = st_wordstart;
 | |
| 
 | |
| 	if (!cmdline_ptr || cmdline_ptr >= 0x100000)
 | |
| 		return -1;	/* No command line, or inaccessible */
 | |
| 
 | |
| 	cptr = cmdline_ptr & 0xf;
 | |
| 	set_fs(cmdline_ptr >> 4);
 | |
| 
 | |
| 	while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
 | |
| 		switch (state) {
 | |
| 		case st_wordstart:
 | |
| 			if (myisspace(c))
 | |
| 				break;
 | |
| 
 | |
| 			/* else */
 | |
| 			state = st_wordcmp;
 | |
| 			opptr = option;
 | |
| 			/* fall through */
 | |
| 
 | |
| 		case st_wordcmp:
 | |
| 			if (c == '=' && !*opptr) {
 | |
| 				len = 0;
 | |
| 				bufptr = buffer;
 | |
| 				state = st_bufcpy;
 | |
| 			} else if (myisspace(c)) {
 | |
| 				state = st_wordstart;
 | |
| 			} else if (c != *opptr++) {
 | |
| 				state = st_wordskip;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case st_wordskip:
 | |
| 			if (myisspace(c))
 | |
| 				state = st_wordstart;
 | |
| 			break;
 | |
| 
 | |
| 		case st_bufcpy:
 | |
| 			if (myisspace(c)) {
 | |
| 				state = st_wordstart;
 | |
| 			} else {
 | |
| 				if (len < bufsize-1)
 | |
| 					*bufptr++ = c;
 | |
| 				len++;
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (bufsize)
 | |
| 		*bufptr = '\0';
 | |
| 
 | |
| 	return len;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Find a boolean option (like quiet,noapic,nosmp....)
 | |
|  *
 | |
|  * Returns the position of that option (starts counting with 1)
 | |
|  * or 0 on not found
 | |
|  */
 | |
| int __cmdline_find_option_bool(u32 cmdline_ptr, const char *option)
 | |
| {
 | |
| 	addr_t cptr;
 | |
| 	char c;
 | |
| 	int pos = 0, wstart = 0;
 | |
| 	const char *opptr = NULL;
 | |
| 	enum {
 | |
| 		st_wordstart,	/* Start of word/after whitespace */
 | |
| 		st_wordcmp,	/* Comparing this word */
 | |
| 		st_wordskip,	/* Miscompare, skip */
 | |
| 	} state = st_wordstart;
 | |
| 
 | |
| 	if (!cmdline_ptr || cmdline_ptr >= 0x100000)
 | |
| 		return -1;	/* No command line, or inaccessible */
 | |
| 
 | |
| 	cptr = cmdline_ptr & 0xf;
 | |
| 	set_fs(cmdline_ptr >> 4);
 | |
| 
 | |
| 	while (cptr < 0x10000) {
 | |
| 		c = rdfs8(cptr++);
 | |
| 		pos++;
 | |
| 
 | |
| 		switch (state) {
 | |
| 		case st_wordstart:
 | |
| 			if (!c)
 | |
| 				return 0;
 | |
| 			else if (myisspace(c))
 | |
| 				break;
 | |
| 
 | |
| 			state = st_wordcmp;
 | |
| 			opptr = option;
 | |
| 			wstart = pos;
 | |
| 			/* fall through */
 | |
| 
 | |
| 		case st_wordcmp:
 | |
| 			if (!*opptr)
 | |
| 				if (!c || myisspace(c))
 | |
| 					return wstart;
 | |
| 				else
 | |
| 					state = st_wordskip;
 | |
| 			else if (!c)
 | |
| 				return 0;
 | |
| 			else if (c != *opptr++)
 | |
| 				state = st_wordskip;
 | |
| 			break;
 | |
| 
 | |
| 		case st_wordskip:
 | |
| 			if (!c)
 | |
| 				return 0;
 | |
| 			else if (myisspace(c))
 | |
| 				state = st_wordstart;
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;	/* Buffer overrun */
 | |
| }
 |