Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* -*- linux-c -*- ------------------------------------------------------- *
0003  *
0004  *   Copyright (C) 1991, 1992 Linus Torvalds
0005  *   Copyright 2007 rPath, Inc. - All Rights Reserved
0006  *
0007  * ----------------------------------------------------------------------- */
0008 
0009 /*
0010  * Simple command-line parser for early boot.
0011  */
0012 
0013 #include "boot.h"
0014 
0015 static inline int myisspace(u8 c)
0016 {
0017     return c <= ' ';    /* Close enough approximation */
0018 }
0019 
0020 /*
0021  * Find a non-boolean option, that is, "option=argument".  In accordance
0022  * with standard Linux practice, if this option is repeated, this returns
0023  * the last instance on the command line.
0024  *
0025  * Returns the length of the argument (regardless of if it was
0026  * truncated to fit in the buffer), or -1 on not found.
0027  */
0028 int __cmdline_find_option(unsigned long cmdline_ptr, const char *option, char *buffer, int bufsize)
0029 {
0030     addr_t cptr;
0031     char c;
0032     int len = -1;
0033     const char *opptr = NULL;
0034     char *bufptr = buffer;
0035     enum {
0036         st_wordstart,   /* Start of word/after whitespace */
0037         st_wordcmp, /* Comparing this word */
0038         st_wordskip,    /* Miscompare, skip */
0039         st_bufcpy   /* Copying this to buffer */
0040     } state = st_wordstart;
0041 
0042     if (!cmdline_ptr)
0043         return -1;      /* No command line */
0044 
0045     cptr = cmdline_ptr & 0xf;
0046     set_fs(cmdline_ptr >> 4);
0047 
0048     while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
0049         switch (state) {
0050         case st_wordstart:
0051             if (myisspace(c))
0052                 break;
0053 
0054             /* else */
0055             state = st_wordcmp;
0056             opptr = option;
0057             fallthrough;
0058 
0059         case st_wordcmp:
0060             if (c == '=' && !*opptr) {
0061                 len = 0;
0062                 bufptr = buffer;
0063                 state = st_bufcpy;
0064             } else if (myisspace(c)) {
0065                 state = st_wordstart;
0066             } else if (c != *opptr++) {
0067                 state = st_wordskip;
0068             }
0069             break;
0070 
0071         case st_wordskip:
0072             if (myisspace(c))
0073                 state = st_wordstart;
0074             break;
0075 
0076         case st_bufcpy:
0077             if (myisspace(c)) {
0078                 state = st_wordstart;
0079             } else {
0080                 if (len < bufsize-1)
0081                     *bufptr++ = c;
0082                 len++;
0083             }
0084             break;
0085         }
0086     }
0087 
0088     if (bufsize)
0089         *bufptr = '\0';
0090 
0091     return len;
0092 }
0093 
0094 /*
0095  * Find a boolean option (like quiet,noapic,nosmp....)
0096  *
0097  * Returns the position of that option (starts counting with 1)
0098  * or 0 on not found
0099  */
0100 int __cmdline_find_option_bool(unsigned long cmdline_ptr, const char *option)
0101 {
0102     addr_t cptr;
0103     char c;
0104     int pos = 0, wstart = 0;
0105     const char *opptr = NULL;
0106     enum {
0107         st_wordstart,   /* Start of word/after whitespace */
0108         st_wordcmp, /* Comparing this word */
0109         st_wordskip,    /* Miscompare, skip */
0110     } state = st_wordstart;
0111 
0112     if (!cmdline_ptr)
0113         return -1;      /* No command line */
0114 
0115     cptr = cmdline_ptr & 0xf;
0116     set_fs(cmdline_ptr >> 4);
0117 
0118     while (cptr < 0x10000) {
0119         c = rdfs8(cptr++);
0120         pos++;
0121 
0122         switch (state) {
0123         case st_wordstart:
0124             if (!c)
0125                 return 0;
0126             else if (myisspace(c))
0127                 break;
0128 
0129             state = st_wordcmp;
0130             opptr = option;
0131             wstart = pos;
0132             fallthrough;
0133 
0134         case st_wordcmp:
0135             if (!*opptr)
0136                 if (!c || myisspace(c))
0137                     return wstart;
0138                 else
0139                     state = st_wordskip;
0140             else if (!c)
0141                 return 0;
0142             else if (c != *opptr++)
0143                 state = st_wordskip;
0144             break;
0145 
0146         case st_wordskip:
0147             if (!c)
0148                 return 0;
0149             else if (myisspace(c))
0150                 state = st_wordstart;
0151             break;
0152         }
0153     }
0154 
0155     return 0;   /* Buffer overrun */
0156 }