1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2012 IBM Corporation
3 \ * All rights reserved.
4 \ * This program and the accompanying materials
5 \ * are made available under the terms of the BSD License
6 \ * which accompanies this distribution, and is available at
7 \ * http://www.opensource.org/licenses/bsd-license.php
10 \ * IBM Corporation - initial implementation
11 \ ****************************************************************************/
14 \ configuration variables
16 wordlist CONSTANT envvars
18 \ list the names in envvars
20 get-current envvars set-current words set-current
23 \ create a definition in envvars
24 : create-env ( "name" -- )
25 get-current envvars set-current CREATE set-current
28 \ lay out the data for the separate envvar types
29 : env-int ( n -- ) 1 c, align , DOES> char+ aligned @ ;
30 : env-bytes ( a len -- )
31 2 c, align dup , here swap dup allot move
32 DOES> char+ aligned dup @ >r cell+ r>
34 : env-string ( str len -- ) 3 c, align dup , here over allot swap move DOES> char+ aligned dup @ >r cell+ r> ;
35 : env-flag ( f -- ) 4 c, c, DOES> char+ c@ 0<> ;
36 : env-secmode ( sm -- ) 5 c, c, DOES> char+ c@ ;
38 \ create default envvars
39 : default-int ( n "name" -- ) create-env env-int ;
40 : default-bytes ( a len "name" -- ) create-env env-bytes ;
41 : default-string ( a len "name" -- ) create-env env-string ;
42 : default-flag ( f "name" -- ) create-env env-flag ;
43 : default-secmode ( sm "name" -- ) create-env env-secmode ;
45 : set-option ( option-name len option len -- )
47 2swap s" /options" find-node dup IF set-property ELSE drop 2drop 2drop THEN
50 \ find an envvar's current and default value, and its type
51 : findenv ( name len -- adr def-adr type | 0 )
52 2dup envvars voc-find dup 0<> IF ( ABORT" not a configuration variable" )
53 link> >body char+ >r (find-order) link> >body dup char+ swap c@ r> swap
60 : test-flag ( param len -- true | false )
61 2dup s" true" string=ci -rot s" false" string=ci or
64 : test-secmode ( param len -- true | false )
65 2dup s" none" string=ci -rot 2dup s" command" string=ci -rot s" full"
69 : test-int ( param len -- true | false )
70 $dh-number IF false ELSE drop true THEN
73 : findtype ( param len name len -- param len name len type )
74 2dup findenv \ try to find type of envvar
75 dup IF \ found a type?
80 \ No type found yet, try to auto-detect:
92 IF 3 ELSE 2 THEN \ 3 = string, 2 = default to bytes
102 : $setenv ( param len name len -- )
107 1 OF $dh-number IF 0 THEN env-int ENDOF \ XXX: wants decimal and 0x...
109 3 OF env-string ENDOF
110 4 OF evaluate env-flag ENDOF
111 5 OF evaluate env-secmode ENDOF \ XXX: recognize none, command, full
116 : (printenv) ( adr type -- )
118 1 OF aligned @ . ENDOF
119 2 OF aligned dup cell+ swap @ swap . . ENDOF
120 3 OF aligned dup @ >r cell+ r> type ENDOF
121 4 OF c@ IF ." true" ELSE ." false" THEN ENDOF
122 5 OF c@ . ENDOF \ XXX: print symbolically
126 : .printenv-header ( -- )
128 s" ---environment variable--------current value-------------default value------"
135 : emit-and-count emit-counter 1 + to emit-counter old-emit ;
137 : .enable-emit-counter
139 ['] emit behavior to old-emit
140 ['] emit-and-count to emit
143 : .disable-emit-counter
144 ['] old-emit behavior to emit
147 : .spaces ( number-of-spaces -- )
155 : .print-one-env ( name len -- )
157 2dup dup -rot type 1c swap - .spaces
160 (printenv) .disable-emit-counter
161 1a emit-counter - .spaces
172 name>string .print-one-env cr
181 findenv dup 0= ABORT" not a configuration variable"
182 rot over cr ." Current: " (printenv)
183 cr ." Default: " (printenv)
187 \ set envvar(s) to default value
188 : (set-default) ( def-xt -- )
189 dup >name name>string $CREATE dup >body c@ >r execute r> CASE
192 3 OF env-string ENDOF
194 5 OF env-secmode ENDOF ENDCASE
197 \ Environment variables might be board specific
199 #include <envvar_defaults.fs>
201 VARIABLE nvoff \ offset in envvar partition
203 : (nvupdate-one) ( adr type -- "value" )
205 1 OF aligned @ (.d) ENDOF
207 3 OF aligned dup @ >r cell+ r> ENDOF
208 4 OF c@ IF s" true" ELSE s" false" THEN ENDOF
209 5 OF c@ (.) ENDOF \ XXX: print symbolically
213 : nvupdate-one ( def-xt -- )
214 >r nvram-partition-type-common get-nvram-partition ( part.addr part.len FALSE|TRUE R: def-xt )
215 ABORT" No valid NVRAM." r> ( part.addr part.len def-xt )
216 >name name>string ( part.addr part.len var.a var.l )
217 2dup findenv nip (nvupdate-one)
218 ( part.addr part.len var.addr var.len val.addr val.len )
224 nvram-partition-type-common get-nvram-partition ABORT" No valid NVRAM."
225 erase-nvram-partition drop
227 BEGIN @ dup WHILE dup link> nvupdate-one REPEAT
232 ." nvupdate is obsolete." cr
236 parse-word envvars voc-find
237 dup 0= ABORT" not a configuration variable" link> (set-default)
242 BEGIN @ dup WHILE dup link> (set-default) REPEAT
246 \ Preset nvram variables in RAM, but do not overwrite them in NVRAM
250 (set-defaults) (nvupdate)
253 : setenv parse-word ( skipws ) 0d parse -leading 2swap $setenv (nvupdate) ;
256 nvram-partition-type-common get-nvram-partition ( addr offset not-found | not-found ) \ find partition header
258 ." No NVRAM common partition, re-initializing..." cr
261 nvram-partition-type-common get-nvram-partition IF ." NVRAM seems to be broken." cr EXIT THEN
263 \ partition header found: read data from nvram
264 drop ( addr ) \ throw away offset
266 dup rzcount dup \ make string from offset and make condition
267 WHILE ( offset offset length )
268 2dup [char] = split \ Split string at equal sign (=)
269 ( offset offset length name len param len )
270 2swap ( offset offset length param len name len )
272 nip \ throw away old string begin
273 + 1+ \ calc new offset
280 : check-for-nvramrc ( -- )
282 s" Executing following code from nvramrc: "
283 s" nvramrc" evaluate $cat
284 nvramlog-write-string-cr
285 s" (!) Executing code specified in nvramrc" type
286 cr s" SLOF Setup = " type
287 \ to remove the string from the console if the nvramrc is broken
288 \ we need to know how many chars are printed
290 s" nvramrc" evaluate ['] evaluate CATCH IF
291 \ dropping the rest of the nvram string
293 \ delete the chars we do not want to see
294 emit-counter 0 DO 8 emit LOOP
295 s" (!) Code in nvramrc triggered exception. "
296 2dup nvramlog-write-string
297 type cr 12 spaces s" Aborting nvramrc execution" 2dup
298 nvramlog-write-string-cr type cr
299 s" SLOF Setup = " type
301 .disable-emit-counter
306 : (nv-findalias) ( alias-ptr alias-len -- pos )
307 \ create a temporary empty string
309 \ append "devalias " to the temporary string
310 s" devalias " string-cat
311 \ append "<name-str>" to the temporary string
312 3 pick 3 pick string-cat
313 \ append a SPACE character to the temporary string
317 \ get position of the temporary string inside of nvramrc
322 : (nv-build-real-entry) ( name-ptr name-len dev-ptr dev-len -- str-ptr str-len )
323 \ create a temporary empty string
325 \ append "devalias " to the temporary string
326 s" devalias " string-cat
327 \ append "<name-ptr>" to the temporary string
329 \ append a SPACE character to the temporary string
331 \ append "<dev-ptr> to the temporary string
333 \ append a CR character to the temporary string
335 \ append a LF character to the temporary string
339 : (nv-build-null-entry) ( name-ptr name-len dev-ptr dev-len -- str-ptr str-len )
343 : (nv-build-nvramrc) ( name-str name-len dev-str dev-len xt-build-entry -- )
344 \ *** PART 1: check if there is still an alias definition available ***
345 ( alias-ptr alias-len path-ptr path-ptr call-build-entry alias-pos )
346 4 pick 4 pick (nv-findalias)
347 \ if our alias definition is a new one
348 dup s" nvramrc" evaluate nip >= IF
351 \ append content of "nvramrc" to the temporary string
352 s" nvramrc" evaluate string-cat
353 \ Allocate the temporary string
355 \ write the string into nvramrc
357 ELSE \ if our alias is still defined in nvramrc
358 \ *** PART 2: calculate the memory size for the new content of nvramrc ***
359 \ add number of bytes needed for nvramrc-prefix to number of bytes needed
361 5 pick 5 pick 5 pick 5 pick 5 pick execute nip over +
362 ( alias-ptr alias-len path-ptr path-ptr build-entry-xt alias-pos tmp-len )
363 \ add number of bytes needed for nvramrc-postfix
364 s" nvramrc" evaluate 3 pick string-at
365 2dup find-nextline string-at nip +
366 \ *** PART 3: build the new content ***
367 \ allocate enough memory for new content
369 ( alias-ptr alias-len path-ptr path-ptr build-entry-xt alias-pos mem len )
371 s" nvramrc" evaluate drop 3 pick string-cat
373 rot >r >r >r execute r> r> 2swap string-cat
374 ( mem, len ) ( R: alias-pos )
375 \ add nvramrc-postfix
376 s" nvramrc" evaluate r> string-at
377 2dup find-nextline string-at string-cat
379 \ write the temporary string into nvramrc and clean up memory
380 2dup s" nvramrc" $setenv free-mem
384 : $nvalias ( name-str name-len dev-str dev-len -- )
385 4dup ['] (nv-build-real-entry) (nv-build-nvramrc)
387 s" true" s" use-nvramrc?" $setenv
391 : nvalias ( "alias-name< >device-specifier<eol>" -- )
392 parse-word parse-word dup 0<> IF
397 " Usage: nvalias (""alias-name< >device-specifier<eol>"" -- )" type
402 : $nvunalias ( name-str name-len -- )
403 s" " ['] (nv-build-null-entry) (nv-build-nvramrc)
407 : nvunalias ( "alias-name< >" -- )
408 parse-word $nvunalias
411 : diagnostic-mode? ( -- diag-switch? ) diag-switch? ;