/* -*- linux-c -*- ------------------------------------------------------- *1*2* Copyright (C) 1991, 1992 Linus Torvalds3* Copyright 2007 rPath, Inc. - All Rights Reserved4*5* This file is part of the Linux kernel, and is made available under6* the terms of the GNU General Public License version 2.7*8* ----------------------------------------------------------------------- */910/*11* Simple command-line parser for early boot.12*/1314#include "boot.h"1516static inline int myisspace(u8 c)17{18return c <= ' '; /* Close enough approximation */19}2021/*22* Find a non-boolean option, that is, "option=argument". In accordance23* with standard Linux practice, if this option is repeated, this returns24* the last instance on the command line.25*26* Returns the length of the argument (regardless of if it was27* truncated to fit in the buffer), or -1 on not found.28*/29int __cmdline_find_option(u32 cmdline_ptr, const char *option, char *buffer, int bufsize)30{31addr_t cptr;32char c;33int len = -1;34const char *opptr = NULL;35char *bufptr = buffer;36enum {37st_wordstart, /* Start of word/after whitespace */38st_wordcmp, /* Comparing this word */39st_wordskip, /* Miscompare, skip */40st_bufcpy /* Copying this to buffer */41} state = st_wordstart;4243if (!cmdline_ptr || cmdline_ptr >= 0x100000)44return -1; /* No command line, or inaccessible */4546cptr = cmdline_ptr & 0xf;47set_fs(cmdline_ptr >> 4);4849while (cptr < 0x10000 && (c = rdfs8(cptr++))) {50switch (state) {51case st_wordstart:52if (myisspace(c))53break;5455/* else */56state = st_wordcmp;57opptr = option;58/* fall through */5960case st_wordcmp:61if (c == '=' && !*opptr) {62len = 0;63bufptr = buffer;64state = st_bufcpy;65} else if (myisspace(c)) {66state = st_wordstart;67} else if (c != *opptr++) {68state = st_wordskip;69}70break;7172case st_wordskip:73if (myisspace(c))74state = st_wordstart;75break;7677case st_bufcpy:78if (myisspace(c)) {79state = st_wordstart;80} else {81if (len < bufsize-1)82*bufptr++ = c;83len++;84}85break;86}87}8889if (bufsize)90*bufptr = '\0';9192return len;93}9495/*96* Find a boolean option (like quiet,noapic,nosmp....)97*98* Returns the position of that option (starts counting with 1)99* or 0 on not found100*/101int __cmdline_find_option_bool(u32 cmdline_ptr, const char *option)102{103addr_t cptr;104char c;105int pos = 0, wstart = 0;106const char *opptr = NULL;107enum {108st_wordstart, /* Start of word/after whitespace */109st_wordcmp, /* Comparing this word */110st_wordskip, /* Miscompare, skip */111} state = st_wordstart;112113if (!cmdline_ptr || cmdline_ptr >= 0x100000)114return -1; /* No command line, or inaccessible */115116cptr = cmdline_ptr & 0xf;117set_fs(cmdline_ptr >> 4);118119while (cptr < 0x10000) {120c = rdfs8(cptr++);121pos++;122123switch (state) {124case st_wordstart:125if (!c)126return 0;127else if (myisspace(c))128break;129130state = st_wordcmp;131opptr = option;132wstart = pos;133/* fall through */134135case st_wordcmp:136if (!*opptr)137if (!c || myisspace(c))138return wstart;139else140state = st_wordskip;141else if (!c)142return 0;143else if (c != *opptr++)144state = st_wordskip;145break;146147case st_wordskip:148if (!c)149return 0;150else if (myisspace(c))151state = st_wordstart;152break;153}154}155156return 0; /* Buffer overrun */157}158159160