]> git.saurik.com Git - apple/xnu.git/blame - pexpert/gen/bootargs.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / pexpert / gen / bootargs.c
CommitLineData
1c79356b 1/*
b0d623f7 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28#include <pexpert/pexpert.h>
6d2010ae 29#include <pexpert/device_tree.h>
1c79356b 30
6d2010ae
A
31static boolean_t isargsep( char c);
32#if !CONFIG_EMBEDDED
33static int argstrcpy(char *from, char *to);
316670eb 34#endif
cf7d32b8 35static int argstrcpy2(char *from,char *to, unsigned maxlen);
6d2010ae
A
36static int argnumcpy(int val, void *to, unsigned maxlen);
37static int getval(char *s, int *val);
38
39extern int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize);
40
316670eb 41
6d2010ae
A
42struct i24 {
43 int32_t i24 : 24;
44 int32_t _pad : 8;
45};
2d21ac55 46
1c79356b
A
47#define NUM 0
48#define STR 1
49
b0d623f7 50#if !defined(__LP64__) && !defined(__arm__)
91447636 51boolean_t
1c79356b 52PE_parse_boot_arg(
91447636
A
53 const char *arg_string,
54 void *arg_ptr)
55{
2d21ac55
A
56 int max_len = -1;
57
58#if CONFIG_EMBEDDED
59 /* Limit arg size to 4 byte when no size is given */
60 max_len = 4;
61#endif
62
63 return PE_parse_boot_argn(arg_string, arg_ptr, max_len);
91447636 64}
b0d623f7 65#endif
91447636
A
66
67boolean_t
68PE_parse_boot_argn(
69 const char *arg_string,
70 void *arg_ptr,
71 int max_len)
1c79356b
A
72{
73 char *args;
74 char *cp, c;
316670eb 75 uintptr_t i;
1c79356b
A
76 int val;
77 boolean_t arg_boolean;
78 boolean_t arg_found;
79
80 args = PE_boot_args();
9bccf70c
A
81 if (*args == '\0') return FALSE;
82
6d2010ae
A
83#if CONFIG_EMBEDDED
84 if (max_len == -1) return FALSE;
85#endif
86
1c79356b
A
87 arg_found = FALSE;
88
b0d623f7 89 while(*args && isargsep(*args)) args++;
1c79356b
A
90
91 while (*args)
92 {
93 if (*args == '-')
94 arg_boolean = TRUE;
95 else
96 arg_boolean = FALSE;
97
98 cp = args;
99 while (!isargsep (*cp) && *cp != '=')
100 cp++;
101 if (*cp != '=' && !arg_boolean)
102 goto gotit;
103
104 c = *cp;
105
106 i = cp-args;
107 if (strncmp(args, arg_string, i) ||
108 (i!=strlen(arg_string)))
109 goto gotit;
110 if (arg_boolean) {
6d2010ae 111 argnumcpy(1, arg_ptr, max_len);
1c79356b
A
112 arg_found = TRUE;
113 break;
114 } else {
b0d623f7 115 while (*cp && isargsep (*cp))
1c79356b
A
116 cp++;
117 if (*cp == '=' && c != '=') {
118 args = cp+1;
119 goto gotit;
120 }
55e303ae 121 if ('_' == *arg_string) /* Force a string copy if the argument name begins with an underscore */
91447636 122 {
2d21ac55
A
123 int hacklen = 17 > max_len ? 17 : max_len;
124 argstrcpy2 (++cp, (char *)arg_ptr, hacklen - 1); /* Hack - terminate after 16 characters */
91447636
A
125 arg_found = TRUE;
126 break;
127 }
1c79356b
A
128 switch (getval(cp, &val))
129 {
130 case NUM:
6d2010ae 131 argnumcpy(val, arg_ptr, max_len);
1c79356b
A
132 arg_found = TRUE;
133 break;
134 case STR:
91447636 135 if(max_len > 0) //max_len of 0 performs no copy at all
2d21ac55 136 argstrcpy2(++cp, (char *)arg_ptr, max_len - 1);
6d2010ae
A
137#if !CONFIG_EMBEDDED
138 else if(max_len == -1) // unreachable on embedded
91447636 139 argstrcpy(++cp, (char *)arg_ptr);
6d2010ae 140#endif
1c79356b
A
141 arg_found = TRUE;
142 break;
143 }
144 goto gotit;
145 }
146gotit:
147 /* Skip over current arg */
148 while(!isargsep(*args)) args++;
149
150 /* Skip leading white space (catch end of args) */
151 while(*args && isargsep(*args)) args++;
152 }
153
154 return(arg_found);
155}
156
6d2010ae
A
157static boolean_t
158isargsep(
1c79356b
A
159 char c)
160{
161 if (c == ' ' || c == '\0' || c == '\t')
162 return(TRUE);
163 else
164 return(FALSE);
165}
166
6d2010ae
A
167#if !CONFIG_EMBEDDED
168static int
1c79356b
A
169argstrcpy(
170 char *from,
171 char *to)
172{
173 int i = 0;
174
175 while (!isargsep(*from)) {
176 i++;
177 *to++ = *from++;
178 }
179 *to = 0;
180 return(i);
181}
6d2010ae 182#endif
1c79356b 183
cf7d32b8 184static int
55e303ae
A
185argstrcpy2(
186 char *from,
187 char *to,
188 unsigned maxlen)
189{
2d21ac55 190 unsigned int i = 0;
55e303ae
A
191
192 while (!isargsep(*from) && i < maxlen) {
193 i++;
194 *to++ = *from++;
195 }
196 *to = 0;
197 return(i);
198}
199
6d2010ae
A
200static int argnumcpy(int val, void *to, unsigned maxlen)
201{
202 switch (maxlen) {
203 case 0:
204 /* No write-back, caller just wants to know if arg was found */
205 break;
206 case 1:
207 *(int8_t *)to = val;
208 break;
209 case 2:
210 *(int16_t *)to = val;
211 break;
212 case 3:
213 /* Unlikely in practice */
214 ((struct i24 *)to)->i24 = val;
215 break;
216 case 4:
217 default:
218 *(int32_t *)to = val;
219 maxlen = 4;
220 break;
221 }
222
223 return (int)maxlen;
224}
225
226static int
1c79356b
A
227getval(
228 char *s,
229 int *val)
230{
0c530ab8 231 unsigned int radix, intval;
2d21ac55 232 unsigned char c;
1c79356b
A
233 int sign = 1;
234
235 if (*s == '=') {
236 s++;
237 if (*s == '-')
238 sign = -1, s++;
239 intval = *s++-'0';
240 radix = 10;
0c530ab8 241 if (intval == 0) {
1c79356b
A
242 switch(*s) {
243
244 case 'x':
245 radix = 16;
246 s++;
247 break;
248
249 case 'b':
250 radix = 2;
251 s++;
252 break;
253
254 case '0': case '1': case '2': case '3':
255 case '4': case '5': case '6': case '7':
256 intval = *s-'0';
257 s++;
258 radix = 8;
259 break;
260
261 default:
262 if (!isargsep(*s))
263 return (STR);
264 }
0c530ab8
A
265 } else if (intval >= radix) {
266 return (STR);
267 }
1c79356b 268 for(;;) {
0c530ab8
A
269 c = *s++;
270 if (isargsep(c))
271 break;
272 if ((radix <= 10) &&
273 ((c >= '0') && (c <= ('9' - (10 - radix))))) {
274 c -= '0';
275 } else if ((radix == 16) &&
276 ((c >= '0') && (c <= '9'))) {
1c79356b 277 c -= '0';
0c530ab8
A
278 } else if ((radix == 16) &&
279 ((c >= 'a') && (c <= 'f'))) {
1c79356b 280 c -= 'a' - 10;
0c530ab8
A
281 } else if ((radix == 16) &&
282 ((c >= 'A') && (c <= 'F'))) {
1c79356b 283 c -= 'A' - 10;
0c530ab8
A
284 } else if (c == 'k' || c == 'K') {
285 sign *= 1024;
1c79356b 286 break;
0c530ab8
A
287 } else if (c == 'm' || c == 'M') {
288 sign *= 1024 * 1024;
289 break;
290 } else if (c == 'g' || c == 'G') {
291 sign *= 1024 * 1024 * 1024;
292 break;
293 } else {
1c79356b 294 return (STR);
0c530ab8 295 }
1c79356b
A
296 if (c >= radix)
297 return (STR);
298 intval *= radix;
299 intval += c;
300 }
0c530ab8
A
301 if (!isargsep(c) && !isargsep(*s))
302 return STR;
1c79356b
A
303 *val = intval * sign;
304 return (NUM);
305 }
306 *val = 1;
307 return (NUM);
308}
b7266188
A
309
310boolean_t
311PE_imgsrc_mount_supported()
312{
313 return TRUE;
314}
6d2010ae
A
315
316boolean_t
317PE_get_default(
318 const char *property_name,
319 void *property_ptr,
320 unsigned int max_property)
321{
322 DTEntry dte;
323 void **property_data;
324 unsigned int property_size;
325
326 /*
327 * Look for the property using the PE DT support.
328 */
329 if (kSuccess == DTLookupEntry(NULL, "/defaults", &dte)) {
330
331 /*
332 * We have a /defaults node, look for the named property.
333 */
334 if (kSuccess != DTGetProperty(dte, property_name, (void **)&property_data, &property_size))
335 return FALSE;
336
337 /*
338 * This would be a fine place to do smart argument size management for 32/64
339 * translation, but for now we'll insist that callers know how big their
340 * default values are.
341 */
342 if (property_size > max_property)
343 return FALSE;
344
345 /*
346 * Copy back the precisely-sized result.
347 */
348 memcpy(property_ptr, property_data, property_size);
349 return TRUE;
350 }
351
352 /*
353 * Look for the property using I/O Kit's DT support.
354 */
355 return IODTGetDefault(property_name, property_ptr, max_property) ? FALSE : TRUE;
356}