xref: /xnu-11417.140.69/pexpert/gen/bootargs.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions  * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
3*43a90889SApple OSS Distributions  *
4*43a90889SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*43a90889SApple OSS Distributions  *
6*43a90889SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*43a90889SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*43a90889SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*43a90889SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*43a90889SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*43a90889SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*43a90889SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*43a90889SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*43a90889SApple OSS Distributions  *
15*43a90889SApple OSS Distributions  * Please obtain a copy of the License at
16*43a90889SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*43a90889SApple OSS Distributions  *
18*43a90889SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*43a90889SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*43a90889SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*43a90889SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*43a90889SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*43a90889SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*43a90889SApple OSS Distributions  * limitations under the License.
25*43a90889SApple OSS Distributions  *
26*43a90889SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*43a90889SApple OSS Distributions  */
28*43a90889SApple OSS Distributions #include <pexpert/pexpert.h>
29*43a90889SApple OSS Distributions #include <pexpert/device_tree.h>
30*43a90889SApple OSS Distributions 
31*43a90889SApple OSS Distributions #if defined(CONFIG_XNUPOST)
32*43a90889SApple OSS Distributions #include <tests/xnupost.h>
33*43a90889SApple OSS Distributions #endif
34*43a90889SApple OSS Distributions 
35*43a90889SApple OSS Distributions typedef boolean_t (*argsep_func_t) (char c);
36*43a90889SApple OSS Distributions 
37*43a90889SApple OSS Distributions static boolean_t isargsep( char c);
38*43a90889SApple OSS Distributions static boolean_t israngesep( char c);
39*43a90889SApple OSS Distributions #if defined(__x86_64__)
40*43a90889SApple OSS Distributions static int argstrcpy(char *from, char *to);
41*43a90889SApple OSS Distributions #endif
42*43a90889SApple OSS Distributions static int argstrcpy2(char *from, char *to, unsigned maxlen);
43*43a90889SApple OSS Distributions static int argnumcpy(long long val, void *to, unsigned maxlen);
44*43a90889SApple OSS Distributions static int getval(char *s, long long *val, argsep_func_t issep, boolean_t skip_equal_sign);
45*43a90889SApple OSS Distributions boolean_t get_range_bounds(char * c, int64_t * lower, int64_t * upper);
46*43a90889SApple OSS Distributions 
47*43a90889SApple OSS Distributions extern int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize);
48*43a90889SApple OSS Distributions #if defined(CONFIG_XNUPOST)
49*43a90889SApple OSS Distributions kern_return_t parse_boot_arg_test(void);
50*43a90889SApple OSS Distributions #endif
51*43a90889SApple OSS Distributions 
52*43a90889SApple OSS Distributions struct i24 {
53*43a90889SApple OSS Distributions 	int32_t i24 : 24;
54*43a90889SApple OSS Distributions 	int32_t _pad : 8;
55*43a90889SApple OSS Distributions };
56*43a90889SApple OSS Distributions 
57*43a90889SApple OSS Distributions #define NUM     0
58*43a90889SApple OSS Distributions #define STR     1
59*43a90889SApple OSS Distributions 
60*43a90889SApple OSS Distributions static boolean_t
PE_parse_boot_argn_internal(char * args,const char * arg_string,void * arg_ptr,int max_len,boolean_t force_string)61*43a90889SApple OSS Distributions PE_parse_boot_argn_internal(
62*43a90889SApple OSS Distributions 	char *args,
63*43a90889SApple OSS Distributions 	const char *arg_string,
64*43a90889SApple OSS Distributions 	void *      arg_ptr,
65*43a90889SApple OSS Distributions 	int         max_len,
66*43a90889SApple OSS Distributions 	boolean_t   force_string)
67*43a90889SApple OSS Distributions {
68*43a90889SApple OSS Distributions 	char *cp, c;
69*43a90889SApple OSS Distributions 	uintptr_t i;
70*43a90889SApple OSS Distributions 	long long val = 0;
71*43a90889SApple OSS Distributions 	boolean_t arg_boolean;
72*43a90889SApple OSS Distributions 	boolean_t arg_found;
73*43a90889SApple OSS Distributions 
74*43a90889SApple OSS Distributions 	if (*args == '\0') {
75*43a90889SApple OSS Distributions 		return FALSE;
76*43a90889SApple OSS Distributions 	}
77*43a90889SApple OSS Distributions 
78*43a90889SApple OSS Distributions #if !defined(__x86_64__)
79*43a90889SApple OSS Distributions 	if (max_len == -1) {
80*43a90889SApple OSS Distributions 		return FALSE;
81*43a90889SApple OSS Distributions 	}
82*43a90889SApple OSS Distributions #endif
83*43a90889SApple OSS Distributions 
84*43a90889SApple OSS Distributions 	arg_found = FALSE;
85*43a90889SApple OSS Distributions 
86*43a90889SApple OSS Distributions 	while (*args && isargsep(*args)) {
87*43a90889SApple OSS Distributions 		args++;
88*43a90889SApple OSS Distributions 	}
89*43a90889SApple OSS Distributions 
90*43a90889SApple OSS Distributions 	while (*args) {
91*43a90889SApple OSS Distributions 		if (*args == '-') {
92*43a90889SApple OSS Distributions 			arg_boolean = TRUE;
93*43a90889SApple OSS Distributions 		} else {
94*43a90889SApple OSS Distributions 			arg_boolean = FALSE;
95*43a90889SApple OSS Distributions 		}
96*43a90889SApple OSS Distributions 
97*43a90889SApple OSS Distributions 		cp = args;
98*43a90889SApple OSS Distributions 		while (!isargsep(*cp) && *cp != '=') {
99*43a90889SApple OSS Distributions 			cp++;
100*43a90889SApple OSS Distributions 		}
101*43a90889SApple OSS Distributions 
102*43a90889SApple OSS Distributions 		c = *cp;
103*43a90889SApple OSS Distributions 
104*43a90889SApple OSS Distributions 		i = cp - args;
105*43a90889SApple OSS Distributions 		if (strncmp(args, arg_string, i) ||
106*43a90889SApple OSS Distributions 		    (i != strlen(arg_string))) {
107*43a90889SApple OSS Distributions 			goto gotit;
108*43a90889SApple OSS Distributions 		}
109*43a90889SApple OSS Distributions 
110*43a90889SApple OSS Distributions 		if (arg_boolean) {
111*43a90889SApple OSS Distributions 			if (max_len > 0) {
112*43a90889SApple OSS Distributions 				if (force_string) {
113*43a90889SApple OSS Distributions 					argstrcpy2("1", arg_ptr, max_len);
114*43a90889SApple OSS Distributions 				} else {
115*43a90889SApple OSS Distributions 					argnumcpy(1, arg_ptr, max_len);/* max_len of 0 performs no copy at all*/
116*43a90889SApple OSS Distributions 				}
117*43a90889SApple OSS Distributions 				arg_found = TRUE;
118*43a90889SApple OSS Distributions 			} else if (max_len == 0) {
119*43a90889SApple OSS Distributions 				arg_found = TRUE;
120*43a90889SApple OSS Distributions 			}
121*43a90889SApple OSS Distributions 			break;
122*43a90889SApple OSS Distributions 		} else {
123*43a90889SApple OSS Distributions 			while (*cp && isargsep(*cp)) {
124*43a90889SApple OSS Distributions 				cp++;
125*43a90889SApple OSS Distributions 			}
126*43a90889SApple OSS Distributions 			if (*cp == '=' && c != '=') {
127*43a90889SApple OSS Distributions 				args = cp + 1;
128*43a90889SApple OSS Distributions 				goto gotit;
129*43a90889SApple OSS Distributions 			}
130*43a90889SApple OSS Distributions 			if ('_' == *arg_string) { /* Force a string copy if the argument name begins with an underscore */
131*43a90889SApple OSS Distributions 				if (max_len > 0) {
132*43a90889SApple OSS Distributions 					int hacklen = 17 > max_len ? 17 : max_len;
133*43a90889SApple OSS Distributions 					argstrcpy2(++cp, (char *)arg_ptr, hacklen - 1);  /* Hack - terminate after 16 characters */
134*43a90889SApple OSS Distributions 					arg_found = TRUE;
135*43a90889SApple OSS Distributions 				} else if (max_len == 0) {
136*43a90889SApple OSS Distributions 					arg_found = TRUE;
137*43a90889SApple OSS Distributions 				}
138*43a90889SApple OSS Distributions 				break;
139*43a90889SApple OSS Distributions 			}
140*43a90889SApple OSS Distributions 			switch (force_string ? STR : getval(cp, &val, isargsep, FALSE)) {
141*43a90889SApple OSS Distributions 			case NUM:
142*43a90889SApple OSS Distributions 				if (max_len > 0) {
143*43a90889SApple OSS Distributions 					argnumcpy(val, arg_ptr, max_len);
144*43a90889SApple OSS Distributions 					arg_found = TRUE;
145*43a90889SApple OSS Distributions 				} else if (max_len == 0) {
146*43a90889SApple OSS Distributions 					arg_found = TRUE;
147*43a90889SApple OSS Distributions 				}
148*43a90889SApple OSS Distributions 				break;
149*43a90889SApple OSS Distributions 			case STR:
150*43a90889SApple OSS Distributions 				if (*cp == '=') {
151*43a90889SApple OSS Distributions 					if (max_len > 0) {
152*43a90889SApple OSS Distributions 						argstrcpy2(++cp, (char *)arg_ptr, max_len - 1);        /*max_len of 0 performs no copy at all*/
153*43a90889SApple OSS Distributions 						arg_found = TRUE;
154*43a90889SApple OSS Distributions 					} else if (max_len == 0) {
155*43a90889SApple OSS Distributions 						arg_found = TRUE;
156*43a90889SApple OSS Distributions 					}
157*43a90889SApple OSS Distributions #if defined(__x86_64__)
158*43a90889SApple OSS Distributions 					else if (max_len == -1) {         /* unreachable on embedded */
159*43a90889SApple OSS Distributions 						argstrcpy(++cp, (char *)arg_ptr);
160*43a90889SApple OSS Distributions 						arg_found = TRUE;
161*43a90889SApple OSS Distributions 					}
162*43a90889SApple OSS Distributions #endif
163*43a90889SApple OSS Distributions 				} else {
164*43a90889SApple OSS Distributions 					if (max_len > 0) {
165*43a90889SApple OSS Distributions 						argstrcpy2("1", arg_ptr, max_len);
166*43a90889SApple OSS Distributions 						arg_found = TRUE;
167*43a90889SApple OSS Distributions 					} else if (max_len == 0) {
168*43a90889SApple OSS Distributions 						arg_found = TRUE;
169*43a90889SApple OSS Distributions 					}
170*43a90889SApple OSS Distributions 				}
171*43a90889SApple OSS Distributions 				break;
172*43a90889SApple OSS Distributions 			}
173*43a90889SApple OSS Distributions 			goto gotit;
174*43a90889SApple OSS Distributions 		}
175*43a90889SApple OSS Distributions gotit:
176*43a90889SApple OSS Distributions 		/* Skip over current arg */
177*43a90889SApple OSS Distributions 		while (!isargsep(*args)) {
178*43a90889SApple OSS Distributions 			args++;
179*43a90889SApple OSS Distributions 		}
180*43a90889SApple OSS Distributions 
181*43a90889SApple OSS Distributions 		/* Skip leading white space (catch end of args) */
182*43a90889SApple OSS Distributions 		while (*args && isargsep(*args)) {
183*43a90889SApple OSS Distributions 			args++;
184*43a90889SApple OSS Distributions 		}
185*43a90889SApple OSS Distributions 	}
186*43a90889SApple OSS Distributions 
187*43a90889SApple OSS Distributions 	return arg_found;
188*43a90889SApple OSS Distributions }
189*43a90889SApple OSS Distributions 
190*43a90889SApple OSS Distributions boolean_t
PE_parse_boot_argn(const char * arg_string,void * arg_ptr,int max_len)191*43a90889SApple OSS Distributions PE_parse_boot_argn(
192*43a90889SApple OSS Distributions 	const char      *arg_string,
193*43a90889SApple OSS Distributions 	void            *arg_ptr,
194*43a90889SApple OSS Distributions 	int                     max_len)
195*43a90889SApple OSS Distributions {
196*43a90889SApple OSS Distributions 	return PE_parse_boot_argn_internal(PE_boot_args(), arg_string, arg_ptr, max_len, FALSE);
197*43a90889SApple OSS Distributions }
198*43a90889SApple OSS Distributions 
199*43a90889SApple OSS Distributions boolean_t
PE_boot_arg_uint64_eq(const char * arg_string,uint64_t value)200*43a90889SApple OSS Distributions PE_boot_arg_uint64_eq(const char *arg_string, uint64_t value)
201*43a90889SApple OSS Distributions {
202*43a90889SApple OSS Distributions 	uint64_t tmp;
203*43a90889SApple OSS Distributions 	if (!PE_parse_boot_argn(arg_string, &tmp, sizeof(tmp))) {
204*43a90889SApple OSS Distributions 		return false;
205*43a90889SApple OSS Distributions 	}
206*43a90889SApple OSS Distributions 
207*43a90889SApple OSS Distributions 	return tmp == value;
208*43a90889SApple OSS Distributions }
209*43a90889SApple OSS Distributions 
210*43a90889SApple OSS Distributions boolean_t
PE_parse_boot_arg_str(const char * arg_string,char * arg_ptr,int strlen)211*43a90889SApple OSS Distributions PE_parse_boot_arg_str(
212*43a90889SApple OSS Distributions 	const char      *arg_string,
213*43a90889SApple OSS Distributions 	char            *arg_ptr,
214*43a90889SApple OSS Distributions 	int                     strlen)
215*43a90889SApple OSS Distributions {
216*43a90889SApple OSS Distributions 	return PE_parse_boot_argn_internal(PE_boot_args(), arg_string, arg_ptr, strlen, TRUE);
217*43a90889SApple OSS Distributions }
218*43a90889SApple OSS Distributions 
219*43a90889SApple OSS Distributions #if defined(CONFIG_XNUPOST)
220*43a90889SApple OSS Distributions kern_return_t
parse_boot_arg_test(void)221*43a90889SApple OSS Distributions parse_boot_arg_test(void)
222*43a90889SApple OSS Distributions {
223*43a90889SApple OSS Distributions 	// Tests are derived from libc/tests/darwin_bsd.c
224*43a90889SApple OSS Distributions 	static struct string_test_case {
225*43a90889SApple OSS Distributions 		char *args;
226*43a90889SApple OSS Distributions 		const char *argname;
227*43a90889SApple OSS Distributions 		char *argvalue;
228*43a90889SApple OSS Distributions 		boolean_t found;
229*43a90889SApple OSS Distributions 	} string_test_cases[] = {
230*43a90889SApple OSS Distributions 		{"-x -a b=3 y=42", "-a", "1", TRUE},
231*43a90889SApple OSS Distributions 		{"-x -a b=3 y=42", "b", "3", TRUE},
232*43a90889SApple OSS Distributions 		{"-x -a b=2 ba=3 y=42", "b", "2", TRUE},
233*43a90889SApple OSS Distributions 		{"-x -a ba=3 b=2 y=42", "b", "2", TRUE},
234*43a90889SApple OSS Distributions 		{"-x -a b=2 ba=3 y=42", "ba", "3", TRUE},
235*43a90889SApple OSS Distributions 		{"-x -a ba=3 b=2 y=42", "ba", "3", TRUE},
236*43a90889SApple OSS Distributions 		{"-x -ab -aa y=42", "-a", NULL, FALSE},
237*43a90889SApple OSS Distributions 		{"-x b=96 y=42", "bx", NULL, FALSE},
238*43a90889SApple OSS Distributions 		{"-x ab=96 y=42", "a", NULL, FALSE},
239*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "notarealthing", NULL,
240*43a90889SApple OSS Distributions 		 FALSE},
241*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "hello", "world", TRUE},
242*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "debug", "0xBAADF00D",
243*43a90889SApple OSS Distributions 		 TRUE},
244*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "-foobar", "1", TRUE},
245*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "abc", "1", TRUE},
246*43a90889SApple OSS Distributions 	};
247*43a90889SApple OSS Distributions 
248*43a90889SApple OSS Distributions 	T_LOG("Testing boot-arg string parsing.\n");
249*43a90889SApple OSS Distributions 	for (int i = 0; i < (int)(sizeof(string_test_cases) /
250*43a90889SApple OSS Distributions 	    sizeof(string_test_cases[0])); i++) {
251*43a90889SApple OSS Distributions 		struct string_test_case *test_case = &string_test_cases[i];
252*43a90889SApple OSS Distributions 
253*43a90889SApple OSS Distributions 		char result[256] = "NOT_FOUND";
254*43a90889SApple OSS Distributions 		boolean_t found = PE_parse_boot_argn_internal(test_case->args,
255*43a90889SApple OSS Distributions 		    test_case->argname, result, sizeof(result), TRUE);
256*43a90889SApple OSS Distributions 
257*43a90889SApple OSS Distributions 		if (test_case->found) {
258*43a90889SApple OSS Distributions 			T_LOG("\"%s\": Looking for \"%s\", expecting \"%s\" found",
259*43a90889SApple OSS Distributions 			    test_case->args, test_case->argname, test_case->argvalue);
260*43a90889SApple OSS Distributions 			T_EXPECT(found, "Should find argument");
261*43a90889SApple OSS Distributions 			T_EXPECT_EQ_STR(result, test_case->argvalue,
262*43a90889SApple OSS Distributions 			    "Should find correct result");
263*43a90889SApple OSS Distributions 		} else {
264*43a90889SApple OSS Distributions 			T_LOG("\"%s\": Looking for \"%s\", expecting not found",
265*43a90889SApple OSS Distributions 			    test_case->args, test_case->argname, test_case->argvalue);
266*43a90889SApple OSS Distributions 			T_EXPECT(!found, "Should not find argument");
267*43a90889SApple OSS Distributions 		}
268*43a90889SApple OSS Distributions 	}
269*43a90889SApple OSS Distributions 
270*43a90889SApple OSS Distributions 	static struct integer_test_case {
271*43a90889SApple OSS Distributions 		char *args;
272*43a90889SApple OSS Distributions 		const char *argname;
273*43a90889SApple OSS Distributions 		int argvalue;
274*43a90889SApple OSS Distributions 		boolean_t found;
275*43a90889SApple OSS Distributions 	} integer_test_cases[] = {
276*43a90889SApple OSS Distributions 		{"-x -a b=3 y=42", "-a", 1, TRUE},
277*43a90889SApple OSS Distributions 		{"-x -a b=3 y=42", "b", 3, TRUE},
278*43a90889SApple OSS Distributions 		{"-x -a b=2 ba=3 y=42", "b", 2, TRUE},
279*43a90889SApple OSS Distributions 		{"-x -a ba=3 b=2 y=42", "b", 2, TRUE},
280*43a90889SApple OSS Distributions 		{"-x -a b=2 ba=3 y=42", "ba", 3, TRUE},
281*43a90889SApple OSS Distributions 		{"-x -a ba=3 b=2 y=42", "ba", 3, TRUE},
282*43a90889SApple OSS Distributions 		{"-x -ab -aa y=42", "-a", 0, FALSE},
283*43a90889SApple OSS Distributions 		{"-x b=96 y=42", "bx", 0, FALSE},
284*43a90889SApple OSS Distributions 		{"-x ab=96 y=42", "a", 0, FALSE},
285*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "notarealthing", 0, FALSE},
286*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "hello",
287*43a90889SApple OSS Distributions 		 0x00726F77 /* "wor" */, TRUE},
288*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "debug", 0xBAADF00D, TRUE},
289*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "-foobar", 1, TRUE},
290*43a90889SApple OSS Distributions 		{"hello=world -foobar abc debug=0xBAADF00D", "abc", 1, TRUE},
291*43a90889SApple OSS Distributions 	};
292*43a90889SApple OSS Distributions 
293*43a90889SApple OSS Distributions 	T_LOG("Testing boot-arg integer parsing.\n");
294*43a90889SApple OSS Distributions 	for (int i = 0; i < (int)(sizeof(integer_test_cases) /
295*43a90889SApple OSS Distributions 	    sizeof(integer_test_cases[0])); i++) {
296*43a90889SApple OSS Distributions 		struct integer_test_case *test_case = &integer_test_cases[i];
297*43a90889SApple OSS Distributions 
298*43a90889SApple OSS Distributions 		int result = 0xCAFEFACE;
299*43a90889SApple OSS Distributions 		boolean_t found = PE_parse_boot_argn_internal(test_case->args,
300*43a90889SApple OSS Distributions 		    test_case->argname, &result, sizeof(result), FALSE);
301*43a90889SApple OSS Distributions 
302*43a90889SApple OSS Distributions 		if (test_case->found) {
303*43a90889SApple OSS Distributions 			T_LOG("\"%s\": Looking for \"%s\", expecting %d found",
304*43a90889SApple OSS Distributions 			    test_case->args, test_case->argname, test_case->argvalue);
305*43a90889SApple OSS Distributions 			T_EXPECT(found, "Should find argument");
306*43a90889SApple OSS Distributions 			T_EXPECT_EQ_INT(result, test_case->argvalue,
307*43a90889SApple OSS Distributions 			    "Should find correct result");
308*43a90889SApple OSS Distributions 		} else {
309*43a90889SApple OSS Distributions 			T_LOG("\"%s\": Looking for \"%s\", expecting not found",
310*43a90889SApple OSS Distributions 			    test_case->args, test_case->argname, test_case->argvalue);
311*43a90889SApple OSS Distributions 			T_EXPECT(!found, "Should not find argument");
312*43a90889SApple OSS Distributions 		}
313*43a90889SApple OSS Distributions 	}
314*43a90889SApple OSS Distributions 
315*43a90889SApple OSS Distributions 	return KERN_SUCCESS;
316*43a90889SApple OSS Distributions }
317*43a90889SApple OSS Distributions #endif /* defined(CONFIG_XNUPOST) */
318*43a90889SApple OSS Distributions 
319*43a90889SApple OSS Distributions static boolean_t
isargsep(char c)320*43a90889SApple OSS Distributions isargsep(char c)
321*43a90889SApple OSS Distributions {
322*43a90889SApple OSS Distributions 	if (c == ' ' || c == '\0' || c == '\t') {
323*43a90889SApple OSS Distributions 		return TRUE;
324*43a90889SApple OSS Distributions 	} else {
325*43a90889SApple OSS Distributions 		return FALSE;
326*43a90889SApple OSS Distributions 	}
327*43a90889SApple OSS Distributions }
328*43a90889SApple OSS Distributions 
329*43a90889SApple OSS Distributions static boolean_t
israngesep(char c)330*43a90889SApple OSS Distributions israngesep(char c)
331*43a90889SApple OSS Distributions {
332*43a90889SApple OSS Distributions 	if (isargsep(c) || c == '_' || c == ',') {
333*43a90889SApple OSS Distributions 		return TRUE;
334*43a90889SApple OSS Distributions 	} else {
335*43a90889SApple OSS Distributions 		return FALSE;
336*43a90889SApple OSS Distributions 	}
337*43a90889SApple OSS Distributions }
338*43a90889SApple OSS Distributions 
339*43a90889SApple OSS Distributions #if defined(__x86_64__)
340*43a90889SApple OSS Distributions static int
argstrcpy(char * from,char * to)341*43a90889SApple OSS Distributions argstrcpy(
342*43a90889SApple OSS Distributions 	char *from,
343*43a90889SApple OSS Distributions 	char *to)
344*43a90889SApple OSS Distributions {
345*43a90889SApple OSS Distributions 	int i = 0;
346*43a90889SApple OSS Distributions 
347*43a90889SApple OSS Distributions 	while (!isargsep(*from)) {
348*43a90889SApple OSS Distributions 		i++;
349*43a90889SApple OSS Distributions 		*to++ = *from++;
350*43a90889SApple OSS Distributions 	}
351*43a90889SApple OSS Distributions 	*to = 0;
352*43a90889SApple OSS Distributions 	return i;
353*43a90889SApple OSS Distributions }
354*43a90889SApple OSS Distributions #endif
355*43a90889SApple OSS Distributions 
356*43a90889SApple OSS Distributions static int
argstrcpy2(char * from,char * to,unsigned maxlen)357*43a90889SApple OSS Distributions argstrcpy2(
358*43a90889SApple OSS Distributions 	char *from,
359*43a90889SApple OSS Distributions 	char *to,
360*43a90889SApple OSS Distributions 	unsigned maxlen)
361*43a90889SApple OSS Distributions {
362*43a90889SApple OSS Distributions 	unsigned int i = 0;
363*43a90889SApple OSS Distributions 
364*43a90889SApple OSS Distributions 	while (!isargsep(*from) && i < maxlen) {
365*43a90889SApple OSS Distributions 		i++;
366*43a90889SApple OSS Distributions 		*to++ = *from++;
367*43a90889SApple OSS Distributions 	}
368*43a90889SApple OSS Distributions 	*to = 0;
369*43a90889SApple OSS Distributions 	return i;
370*43a90889SApple OSS Distributions }
371*43a90889SApple OSS Distributions 
372*43a90889SApple OSS Distributions static int
argnumcpy(long long val,void * to,unsigned maxlen)373*43a90889SApple OSS Distributions argnumcpy(long long val, void *to, unsigned maxlen)
374*43a90889SApple OSS Distributions {
375*43a90889SApple OSS Distributions 	switch (maxlen) {
376*43a90889SApple OSS Distributions 	case 0:
377*43a90889SApple OSS Distributions 		/* No write-back, caller just wants to know if arg was found */
378*43a90889SApple OSS Distributions 		break;
379*43a90889SApple OSS Distributions 	case 1:
380*43a90889SApple OSS Distributions 		*(int8_t *)to = (int8_t)val;
381*43a90889SApple OSS Distributions 		break;
382*43a90889SApple OSS Distributions 	case 2:
383*43a90889SApple OSS Distributions 		*(int16_t *)to = (int16_t)val;
384*43a90889SApple OSS Distributions 		break;
385*43a90889SApple OSS Distributions 	case 3:
386*43a90889SApple OSS Distributions 		/* Unlikely in practice */
387*43a90889SApple OSS Distributions 		((struct i24 *)to)->i24 = (int32_t)val;
388*43a90889SApple OSS Distributions 		break;
389*43a90889SApple OSS Distributions 	case 4:
390*43a90889SApple OSS Distributions 		*(int32_t *)to = (int32_t)val;
391*43a90889SApple OSS Distributions 		break;
392*43a90889SApple OSS Distributions 	case 8:
393*43a90889SApple OSS Distributions 		*(int64_t *)to = (int64_t)val;
394*43a90889SApple OSS Distributions 		break;
395*43a90889SApple OSS Distributions 	default:
396*43a90889SApple OSS Distributions 		*(int32_t *)to = (int32_t)val;
397*43a90889SApple OSS Distributions 		maxlen = 4;
398*43a90889SApple OSS Distributions 		break;
399*43a90889SApple OSS Distributions 	}
400*43a90889SApple OSS Distributions 
401*43a90889SApple OSS Distributions 	return (int)maxlen;
402*43a90889SApple OSS Distributions }
403*43a90889SApple OSS Distributions 
404*43a90889SApple OSS Distributions static int
getval(char * s,long long * val,argsep_func_t issep,boolean_t skip_equal_sign)405*43a90889SApple OSS Distributions getval(
406*43a90889SApple OSS Distributions 	char *s,
407*43a90889SApple OSS Distributions 	long long *val,
408*43a90889SApple OSS Distributions 	argsep_func_t issep,
409*43a90889SApple OSS Distributions 	boolean_t skip_equal_sign )
410*43a90889SApple OSS Distributions {
411*43a90889SApple OSS Distributions 	unsigned long long radix, intval;
412*43a90889SApple OSS Distributions 	unsigned char c;
413*43a90889SApple OSS Distributions 	int sign = 1;
414*43a90889SApple OSS Distributions 	boolean_t has_value = FALSE;
415*43a90889SApple OSS Distributions 
416*43a90889SApple OSS Distributions 	if (*s == '=') {
417*43a90889SApple OSS Distributions 		s++;
418*43a90889SApple OSS Distributions 		has_value = TRUE;
419*43a90889SApple OSS Distributions 	}
420*43a90889SApple OSS Distributions 
421*43a90889SApple OSS Distributions 	if (has_value || skip_equal_sign) {
422*43a90889SApple OSS Distributions 		if (*s == '-') {
423*43a90889SApple OSS Distributions 			sign = -1;
424*43a90889SApple OSS Distributions 			s++;
425*43a90889SApple OSS Distributions 		}
426*43a90889SApple OSS Distributions 		intval = *s++ - '0';
427*43a90889SApple OSS Distributions 		radix = 10;
428*43a90889SApple OSS Distributions 		if (intval == 0) {
429*43a90889SApple OSS Distributions 			switch (*s) {
430*43a90889SApple OSS Distributions 			case 'x':
431*43a90889SApple OSS Distributions 				radix = 16;
432*43a90889SApple OSS Distributions 				s++;
433*43a90889SApple OSS Distributions 				break;
434*43a90889SApple OSS Distributions 
435*43a90889SApple OSS Distributions 			case 'b':
436*43a90889SApple OSS Distributions 				radix = 2;
437*43a90889SApple OSS Distributions 				s++;
438*43a90889SApple OSS Distributions 				break;
439*43a90889SApple OSS Distributions 
440*43a90889SApple OSS Distributions 			case '0': case '1': case '2': case '3':
441*43a90889SApple OSS Distributions 			case '4': case '5': case '6': case '7':
442*43a90889SApple OSS Distributions 				intval = *s - '0';
443*43a90889SApple OSS Distributions 				s++;
444*43a90889SApple OSS Distributions 				radix = 8;
445*43a90889SApple OSS Distributions 				break;
446*43a90889SApple OSS Distributions 
447*43a90889SApple OSS Distributions 			default:
448*43a90889SApple OSS Distributions 				if (!issep(*s)) {
449*43a90889SApple OSS Distributions 					return STR;
450*43a90889SApple OSS Distributions 				}
451*43a90889SApple OSS Distributions 			}
452*43a90889SApple OSS Distributions 		} else if (intval >= radix) {
453*43a90889SApple OSS Distributions 			return STR;
454*43a90889SApple OSS Distributions 		}
455*43a90889SApple OSS Distributions 		for (;;) {
456*43a90889SApple OSS Distributions 			c = *s++;
457*43a90889SApple OSS Distributions 			if (issep(c)) {
458*43a90889SApple OSS Distributions 				break;
459*43a90889SApple OSS Distributions 			}
460*43a90889SApple OSS Distributions 			if ((radix <= 10) &&
461*43a90889SApple OSS Distributions 			    ((c >= '0') && (c <= ('9' - (10 - radix))))) {
462*43a90889SApple OSS Distributions 				c -= '0';
463*43a90889SApple OSS Distributions 			} else if ((radix == 16) &&
464*43a90889SApple OSS Distributions 			    ((c >= '0') && (c <= '9'))) {
465*43a90889SApple OSS Distributions 				c -= '0';
466*43a90889SApple OSS Distributions 			} else if ((radix == 16) &&
467*43a90889SApple OSS Distributions 			    ((c >= 'a') && (c <= 'f'))) {
468*43a90889SApple OSS Distributions 				c -= 'a' - 10;
469*43a90889SApple OSS Distributions 			} else if ((radix == 16) &&
470*43a90889SApple OSS Distributions 			    ((c >= 'A') && (c <= 'F'))) {
471*43a90889SApple OSS Distributions 				c -= 'A' - 10;
472*43a90889SApple OSS Distributions 			} else if (c == 'k' || c == 'K') {
473*43a90889SApple OSS Distributions 				sign *= 1024;
474*43a90889SApple OSS Distributions 				break;
475*43a90889SApple OSS Distributions 			} else if (c == 'm' || c == 'M') {
476*43a90889SApple OSS Distributions 				sign *= 1024 * 1024;
477*43a90889SApple OSS Distributions 				break;
478*43a90889SApple OSS Distributions 			} else if (c == 'g' || c == 'G') {
479*43a90889SApple OSS Distributions 				sign *= 1024 * 1024 * 1024;
480*43a90889SApple OSS Distributions 				break;
481*43a90889SApple OSS Distributions 			} else {
482*43a90889SApple OSS Distributions 				return STR;
483*43a90889SApple OSS Distributions 			}
484*43a90889SApple OSS Distributions 			if (c >= radix) {
485*43a90889SApple OSS Distributions 				return STR;
486*43a90889SApple OSS Distributions 			}
487*43a90889SApple OSS Distributions 			intval *= radix;
488*43a90889SApple OSS Distributions 			intval += c;
489*43a90889SApple OSS Distributions 		}
490*43a90889SApple OSS Distributions 		if (!issep(c) && !issep(*s)) {
491*43a90889SApple OSS Distributions 			return STR;
492*43a90889SApple OSS Distributions 		}
493*43a90889SApple OSS Distributions 		*val = intval * sign;
494*43a90889SApple OSS Distributions 		return NUM;
495*43a90889SApple OSS Distributions 	}
496*43a90889SApple OSS Distributions 	*val = 1;
497*43a90889SApple OSS Distributions 	return NUM;
498*43a90889SApple OSS Distributions }
499*43a90889SApple OSS Distributions 
500*43a90889SApple OSS Distributions boolean_t
PE_imgsrc_mount_supported()501*43a90889SApple OSS Distributions PE_imgsrc_mount_supported()
502*43a90889SApple OSS Distributions {
503*43a90889SApple OSS Distributions 	return TRUE;
504*43a90889SApple OSS Distributions }
505*43a90889SApple OSS Distributions 
506*43a90889SApple OSS Distributions boolean_t
PE_get_default(const char * property_name,void * property_ptr,unsigned int max_property)507*43a90889SApple OSS Distributions PE_get_default(
508*43a90889SApple OSS Distributions 	const char      *property_name,
509*43a90889SApple OSS Distributions 	void            *property_ptr,
510*43a90889SApple OSS Distributions 	unsigned int max_property)
511*43a90889SApple OSS Distributions {
512*43a90889SApple OSS Distributions 	DTEntry         dte;
513*43a90889SApple OSS Distributions 	void const      *property_data;
514*43a90889SApple OSS Distributions 	unsigned int property_size;
515*43a90889SApple OSS Distributions 
516*43a90889SApple OSS Distributions 	/*
517*43a90889SApple OSS Distributions 	 * Look for the property using the PE DT support.
518*43a90889SApple OSS Distributions 	 */
519*43a90889SApple OSS Distributions 	if (kSuccess == SecureDTLookupEntry(NULL, "/defaults", &dte)) {
520*43a90889SApple OSS Distributions 		/*
521*43a90889SApple OSS Distributions 		 * We have a /defaults node, look for the named property.
522*43a90889SApple OSS Distributions 		 */
523*43a90889SApple OSS Distributions 		if (kSuccess != SecureDTGetProperty(dte, property_name, &property_data, &property_size)) {
524*43a90889SApple OSS Distributions 			return FALSE;
525*43a90889SApple OSS Distributions 		}
526*43a90889SApple OSS Distributions 
527*43a90889SApple OSS Distributions 		/*
528*43a90889SApple OSS Distributions 		 * This would be a fine place to do smart argument size management for 32/64
529*43a90889SApple OSS Distributions 		 * translation, but for now we'll insist that callers know how big their
530*43a90889SApple OSS Distributions 		 * default values are.
531*43a90889SApple OSS Distributions 		 */
532*43a90889SApple OSS Distributions 		if (property_size > max_property) {
533*43a90889SApple OSS Distributions 			return FALSE;
534*43a90889SApple OSS Distributions 		}
535*43a90889SApple OSS Distributions 
536*43a90889SApple OSS Distributions 		/*
537*43a90889SApple OSS Distributions 		 * Copy back the precisely-sized result.
538*43a90889SApple OSS Distributions 		 */
539*43a90889SApple OSS Distributions 		memcpy(property_ptr, property_data, property_size);
540*43a90889SApple OSS Distributions 		return TRUE;
541*43a90889SApple OSS Distributions 	}
542*43a90889SApple OSS Distributions 
543*43a90889SApple OSS Distributions 	/*
544*43a90889SApple OSS Distributions 	 * Look for the property using I/O Kit's DT support.
545*43a90889SApple OSS Distributions 	 */
546*43a90889SApple OSS Distributions 	return IODTGetDefault(property_name, property_ptr, max_property) ? FALSE : TRUE;
547*43a90889SApple OSS Distributions }
548*43a90889SApple OSS Distributions 
549*43a90889SApple OSS Distributions /* function: get_range_bounds
550*43a90889SApple OSS Distributions  * Parse a range string like "1_3,10,15_20" and return 1,3 as lower and upper.
551*43a90889SApple OSS Distributions  * Note: '_' is separator for bounds integer delimiter and
552*43a90889SApple OSS Distributions  *       ',' is considered as separator for range pair.
553*43a90889SApple OSS Distributions  * returns TRUE when both range values are found
554*43a90889SApple OSS Distributions  */
555*43a90889SApple OSS Distributions boolean_t
get_range_bounds(char * c,int64_t * lower,int64_t * upper)556*43a90889SApple OSS Distributions get_range_bounds(char *c, int64_t *lower, int64_t *upper)
557*43a90889SApple OSS Distributions {
558*43a90889SApple OSS Distributions 	if (c == NULL || lower == NULL || upper == NULL) {
559*43a90889SApple OSS Distributions 		return FALSE;
560*43a90889SApple OSS Distributions 	}
561*43a90889SApple OSS Distributions 
562*43a90889SApple OSS Distributions 	if (NUM != getval(c, lower, israngesep, TRUE)) {
563*43a90889SApple OSS Distributions 		return FALSE;
564*43a90889SApple OSS Distributions 	}
565*43a90889SApple OSS Distributions 
566*43a90889SApple OSS Distributions 	while (*c != '\0') {
567*43a90889SApple OSS Distributions 		if (*c == '_' || *c == ',') {
568*43a90889SApple OSS Distributions 			break;
569*43a90889SApple OSS Distributions 		}
570*43a90889SApple OSS Distributions 		c++;
571*43a90889SApple OSS Distributions 	}
572*43a90889SApple OSS Distributions 
573*43a90889SApple OSS Distributions 	if (*c == '_') {
574*43a90889SApple OSS Distributions 		c++;
575*43a90889SApple OSS Distributions 		if (NUM != getval(c, upper, israngesep, TRUE)) {
576*43a90889SApple OSS Distributions 			return FALSE;
577*43a90889SApple OSS Distributions 		}
578*43a90889SApple OSS Distributions 	} else {
579*43a90889SApple OSS Distributions 		return FALSE;
580*43a90889SApple OSS Distributions 	}
581*43a90889SApple OSS Distributions 	return TRUE;
582*43a90889SApple OSS Distributions }
583