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