cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cmdline.c (3191B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* -*- linux-c -*- ------------------------------------------------------- *
      3 *
      4 *   Copyright (C) 1991, 1992 Linus Torvalds
      5 *   Copyright 2007 rPath, Inc. - All Rights Reserved
      6 *
      7 * ----------------------------------------------------------------------- */
      8
      9/*
     10 * Simple command-line parser for early boot.
     11 */
     12
     13#include "boot.h"
     14
     15static inline int myisspace(u8 c)
     16{
     17	return c <= ' ';	/* Close enough approximation */
     18}
     19
     20/*
     21 * Find a non-boolean option, that is, "option=argument".  In accordance
     22 * with standard Linux practice, if this option is repeated, this returns
     23 * the last instance on the command line.
     24 *
     25 * Returns the length of the argument (regardless of if it was
     26 * truncated to fit in the buffer), or -1 on not found.
     27 */
     28int __cmdline_find_option(unsigned long cmdline_ptr, const char *option, char *buffer, int bufsize)
     29{
     30	addr_t cptr;
     31	char c;
     32	int len = -1;
     33	const char *opptr = NULL;
     34	char *bufptr = buffer;
     35	enum {
     36		st_wordstart,	/* Start of word/after whitespace */
     37		st_wordcmp,	/* Comparing this word */
     38		st_wordskip,	/* Miscompare, skip */
     39		st_bufcpy	/* Copying this to buffer */
     40	} state = st_wordstart;
     41
     42	if (!cmdline_ptr)
     43		return -1;      /* No command line */
     44
     45	cptr = cmdline_ptr & 0xf;
     46	set_fs(cmdline_ptr >> 4);
     47
     48	while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
     49		switch (state) {
     50		case st_wordstart:
     51			if (myisspace(c))
     52				break;
     53
     54			/* else */
     55			state = st_wordcmp;
     56			opptr = option;
     57			fallthrough;
     58
     59		case st_wordcmp:
     60			if (c == '=' && !*opptr) {
     61				len = 0;
     62				bufptr = buffer;
     63				state = st_bufcpy;
     64			} else if (myisspace(c)) {
     65				state = st_wordstart;
     66			} else if (c != *opptr++) {
     67				state = st_wordskip;
     68			}
     69			break;
     70
     71		case st_wordskip:
     72			if (myisspace(c))
     73				state = st_wordstart;
     74			break;
     75
     76		case st_bufcpy:
     77			if (myisspace(c)) {
     78				state = st_wordstart;
     79			} else {
     80				if (len < bufsize-1)
     81					*bufptr++ = c;
     82				len++;
     83			}
     84			break;
     85		}
     86	}
     87
     88	if (bufsize)
     89		*bufptr = '\0';
     90
     91	return len;
     92}
     93
     94/*
     95 * Find a boolean option (like quiet,noapic,nosmp....)
     96 *
     97 * Returns the position of that option (starts counting with 1)
     98 * or 0 on not found
     99 */
    100int __cmdline_find_option_bool(unsigned long cmdline_ptr, const char *option)
    101{
    102	addr_t cptr;
    103	char c;
    104	int pos = 0, wstart = 0;
    105	const char *opptr = NULL;
    106	enum {
    107		st_wordstart,	/* Start of word/after whitespace */
    108		st_wordcmp,	/* Comparing this word */
    109		st_wordskip,	/* Miscompare, skip */
    110	} state = st_wordstart;
    111
    112	if (!cmdline_ptr)
    113		return -1;      /* No command line */
    114
    115	cptr = cmdline_ptr & 0xf;
    116	set_fs(cmdline_ptr >> 4);
    117
    118	while (cptr < 0x10000) {
    119		c = rdfs8(cptr++);
    120		pos++;
    121
    122		switch (state) {
    123		case st_wordstart:
    124			if (!c)
    125				return 0;
    126			else if (myisspace(c))
    127				break;
    128
    129			state = st_wordcmp;
    130			opptr = option;
    131			wstart = pos;
    132			fallthrough;
    133
    134		case st_wordcmp:
    135			if (!*opptr)
    136				if (!c || myisspace(c))
    137					return wstart;
    138				else
    139					state = st_wordskip;
    140			else if (!c)
    141				return 0;
    142			else if (c != *opptr++)
    143				state = st_wordskip;
    144			break;
    145
    146		case st_wordskip:
    147			if (!c)
    148				return 0;
    149			else if (myisspace(c))
    150				state = st_wordstart;
    151			break;
    152		}
    153	}
    154
    155	return 0;	/* Buffer overrun */
    156}