xref: /titanic_51/usr/src/boot/sys/boot/forth/menu-commands.4th (revision a281b0ef076f3b6cd24864ecb984a4b92dd8b1b8)
1\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
2\ All rights reserved.
3\
4\ Redistribution and use in source and binary forms, with or without
5\ modification, are permitted provided that the following conditions
6\ are met:
7\ 1. Redistributions of source code must retain the above copyright
8\    notice, this list of conditions and the following disclaimer.
9\ 2. Redistributions in binary form must reproduce the above copyright
10\    notice, this list of conditions and the following disclaimer in the
11\    documentation and/or other materials provided with the distribution.
12\
13\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16\ ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23\ SUCH DAMAGE.
24\
25\ Copyright 2015 Toomas Soome <tsoome@me.com>
26
27marker task-menu-commands.4th
28
29include /boot/forth/menusets.4th
30
31only forth definitions
32
33variable osconsole_state
34variable acpi_state
35variable kernel_state
36variable root_state
37variable kmdb_state
38variable debug_state
390 kmdb_state !
400 debug_state !
410 osconsole_state !
420 acpi_state !
430 kernel_state !
440 root_state !
45
46also menu-namespace also menu-command-helpers
47
48\
49\ Boot
50\
51
52: init_boot ( N -- N )
53	dup
54	s" smartos" getenv? if
55		s" set menu_keycode[N]=98" \ base command to execute
56	else
57		s" boot_single" getenv -1 <> if
58			drop ( n n c-addr -- n n ) \ unused
59			toggle_menuitem ( n n -- n n )
60			s" set menu_keycode[N]=115" \ base command to execute
61		else
62			s" set menu_keycode[N]=98" \ base command to execute
63		then
64	then
65	17 +c! \ replace 'N' with ASCII numeral
66	evaluate
67;
68
69\
70\ Alternate Boot
71\
72
73: init_altboot ( N -- N )
74	dup
75	s" smartos" getenv? if
76		s" set menu_keycode[N]=114" \ base command to execute
77	else
78		s" boot_single" getenv -1 <> if
79			drop ( n c-addr -- n ) \ unused
80			toggle_menuitem ( n -- n )
81			s" set menu_keycode[N]=109" \ base command to execute
82		else
83			s" set menu_keycode[N]=115" \ base command to execute
84		then
85	then
86	17 +c! \ replace 'N' with ASCII numeral
87	evaluate
88;
89
90: altboot ( N -- NOTREACHED )
91	s" smartos" getenv? if
92		s" alt-boot-args" getenv dup -1 <> if
93			s" boot-args" setenv ( c-addr/u -- )
94		then
95		." NoInstall/Recovery mode boot. login/pw: root/root" cr
96	else
97		s" boot_single" 2dup getenv -1 <> if
98			drop ( c-addr/u c-addr -- c-addr/u ) \ unused
99			unsetenv ( c-addr/u -- )
100		else
101			2drop ( c-addr/u -- ) \ unused
102			s" set boot_single=YES" evaluate
103		then
104	then
105	0 boot ( state -- )
106;
107
108\
109\ Single User Mode
110\
111
112: singleuser_enabled? ( -- flag )
113	s" boot_single" getenv -1 <> dup if
114		swap drop ( c-addr flag -- flag )
115	then
116;
117
118: singleuser_enable ( -- )
119	s" set boot_single=YES" evaluate
120;
121
122: singleuser_disable ( -- )
123	s" boot_single" unsetenv
124;
125
126: init_singleuser ( N -- N )
127	singleuser_enabled? if
128		toggle_menuitem ( n -- n )
129	then
130;
131
132: toggle_singleuser ( N -- N TRUE )
133	toggle_menuitem
134	menu-redraw
135
136	\ Now we're going to make the change effective
137
138	dup toggle_stateN @ 0= if
139		singleuser_disable
140	else
141		singleuser_enable
142	then
143
144	TRUE \ loop menu again
145;
146
147\
148\ Verbose Boot
149\
150
151: verbose_enabled? ( -- flag )
152	s" boot_verbose" getenv -1 <> dup if
153		swap drop ( c-addr flag -- flag )
154	then
155;
156
157: verbose_enable ( -- )
158	s" set boot_verbose=YES" evaluate
159;
160
161: verbose_disable ( -- )
162	s" boot_verbose" unsetenv
163;
164
165: init_verbose ( N -- N )
166	verbose_enabled? if
167		toggle_menuitem ( n -- n )
168	then
169;
170
171: toggle_verbose ( N -- N TRUE )
172	toggle_menuitem
173	menu-redraw
174
175	\ Now we're going to make the change effective
176
177	dup toggle_stateN @ 0= if
178		verbose_disable
179	else
180		verbose_enable
181	then
182
183	TRUE \ loop menu again
184;
185
186\
187\ kmdb
188\
189
190: kmdb_enabled? ( -- flag )
191	s" boot_kmdb" getenv -1 <> dup if
192		swap drop ( c-addr flag -- flag )
193	then
194;
195
196: kmdb_enable ( -- )
197	s" set boot_kmdb=YES" evaluate
198;
199
200: kmdb_disable ( -- )
201	s" boot_kmdb" unsetenv
202	s" boot_debug" unsetenv
203;
204
205: init_kmdb ( N -- N )
206	dup kmdb_state !		\ store entry number for kmdb+debug
207	kmdb_enabled? if
208		toggle_menuitem ( n -- n )
209	then
210;
211
212: toggle_kmdb ( N -- N TRUE )
213	toggle_menuitem
214	dup toggle_stateN @ 0= if ( kmdb is not set )
215		debug_state @ if ( debug is set? )
216			debug_state @ toggle_stateN @ if ( debug is enabled? )
217				debug_state @ toggle_menuitem drop
218			then
219		then
220	then
221	menu-redraw
222
223	\ Now we're going to make the change effective
224
225	dup toggle_stateN @ 0= if
226		kmdb_disable
227	else
228		kmdb_enable
229	then
230
231	TRUE \ loop menu again
232;
233
234\
235\ kmdb + debug
236\
237
238: debug_disable ( -- )
239	s" boot_debug" unsetenv
240;
241
242: debug_enabled? ( -- flag )
243	\ -d is only allowed with -k
244	s" boot_debug" getenv -1 <> kmdb_enabled? and dup if
245		swap drop ( c-addr flag -- flag )
246	else
247		debug_disable		\ make sure env is not set
248	then
249;
250
251: debug_enable ( -- )
252	kmdb_enable
253	s" set boot_debug=YES" evaluate
254;
255
256: init_debug ( N -- N )
257	dup debug_state !		\ store entry number for kmdb
258	kmdb_enabled? debug_enabled? and if
259		toggle_menuitem ( n -- n )
260	then
261;
262
263: toggle_debug ( N -- N TRUE )
264	toggle_menuitem
265	kmdb_enabled? 0= if
266		kmdb_state @ toggle_menuitem drop
267	then
268	menu-redraw
269
270	\ Now we're going to make the change effective
271
272	dup toggle_stateN @ 0= if
273		debug_disable
274	else
275		debug_enable
276	then
277
278	TRUE \ loop menu again
279;
280
281\
282\ Reconfiguration boot
283\
284
285: reconfigure_enabled? ( -- flag )
286	s" boot_reconfigure" getenv -1 <> dup if
287		swap drop ( c-addr flag -- flag )
288	then
289;
290
291: reconfigure_enable ( -- )
292	s" set boot_reconfigure=YES" evaluate
293;
294
295: reconfigure_disable ( -- )
296	s" boot_reconfigure" unsetenv
297;
298
299: init_reconfigure ( N -- N )
300	reconfigure_enabled? if
301		toggle_menuitem ( n -- n )
302	then
303;
304
305: toggle_reconfigure ( N -- N TRUE )
306	toggle_menuitem
307	menu-redraw
308
309	\ Now we're going to make the change effective
310
311	dup toggle_stateN @ 0= if
312		reconfigure_disable
313	else
314		reconfigure_enable
315	then
316
317	TRUE \ loop menu again
318;
319
320\
321\ Escape to Prompt
322\
323
324: goto_prompt ( N -- N FALSE )
325
326	s" set autoboot_delay=NO" evaluate
327
328	cr
329	." To get back to the menu, type `menu' and press ENTER" cr
330	." or type `boot' and press ENTER to start illumos." cr
331	cr
332
333	FALSE \ exit the menu
334;
335
336\
337\ Cyclestate (used by osconsole/acpi/kernel/root below)
338\
339
340: init_cyclestate ( N K -- N )
341	over cycle_stateN ( n k -- n k addr )
342	begin
343		tuck @  ( n k addr -- n addr k c )
344		over <> ( n addr k c -- n addr k 0|-1 )
345	while
346		rot ( n addr k -- addr k n )
347		cycle_menuitem
348		swap rot ( addr k n -- n k addr )
349	repeat
350	2drop ( n k addr -- n )
351;
352
353\
354\ OS Console
355\ getenv os_console, if not set getenv console, if not set, default to "text"
356\ allowed serial consoles: ttya .. ttyd
357\ if new console will be added (graphics?), this section needs to be updated
358\
359: init_osconsole ( N -- N )
360	s" os_console" getenv dup -1 = if
361		drop
362		s" console" getenv dup -1 = if
363			drop 0		\ default to text
364		then
365	then				( n c-addr/u | n 0 )
366
367	dup 0<> if			( n c-addr/u )
368		2dup s" ttyd" compare 0= if
369			2drop 4
370		else 2dup s" ttyc" compare 0= if
371			2drop 3
372		else 2dup s" ttyb" compare 0= if
373			2drop 2
374		else 2dup s" ttya" compare 0= if
375			2drop 1
376		else
377			2drop 0		\ anything else defaults to text
378		then then then then
379	then
380	osconsole_state !
381;
382
383: activate_osconsole ( N -- N )
384	dup cycle_stateN @	( n -- n n2 )
385	dup osconsole_state !	( n n2 -- n n2 )  \ copy for re-initialization
386
387	case
388	0 of s" text" endof
389	1 of s" ttya" endof
390	2 of s" ttyb" endof
391	3 of s" ttyc" endof
392	4 of s" ttyd" endof
393	dup s" unknown state: " type . cr
394	endcase
395	s" os_console" setenv
396;
397
398: cycle_osconsole ( N -- N TRUE )
399	cycle_menuitem	\ cycle cycle_stateN to next value
400	activate_osconsole	\ apply current cycle_stateN
401	menu-redraw	\ redraw menu
402	TRUE		\ loop menu again
403;
404
405\
406\ ACPI
407\
408: init_acpi ( N -- N )
409	s" acpi-user-options" getenv dup -1 <> if
410		evaluate		\ use ?number parse step
411
412		\ translate option to cycle state
413		case
414		1 of 1 acpi_state ! endof
415		2 of 2 acpi_state ! endof
416		4 of 3 acpi_state ! endof
417		8 of 4 acpi_state ! endof
418		0 acpi_state !
419		endcase
420	else
421		drop
422	then
423;
424
425: activate_acpi ( N -- N )
426	dup cycle_stateN @	( n -- n n2 )
427	dup acpi_state !	( n n2 -- n n2 )  \ copy for re-initialization
428
429	\ if N == 0, it's default, just unset env.
430	dup 0= if
431		drop
432		s" acpi-user-options" unsetenv
433	else
434		case
435		1 of s" 1" endof
436		2 of s" 2" endof
437		3 of s" 4" endof
438		4 of s" 8" endof
439		endcase
440		s" acpi-user-options" setenv
441	then
442;
443
444: cycle_acpi ( N -- N TRUE )
445	cycle_menuitem	\ cycle cycle_stateN to next value
446	activate_acpi	\ apply current cycle_stateN
447	menu-redraw	\ redraw menu
448	TRUE		\ loop menu again
449;
450
451\
452\ Kernel
453\
454
455: init_kernel ( N -- N )
456	kernel_state @  ( n -- n k )
457	init_cyclestate ( n k -- n )
458;
459
460: activate_kernel ( N -- N )
461	dup cycle_stateN @	( n -- n n2 )
462	dup kernel_state !	( n n2 -- n n2 )  \ copy for re-initialization
463	48 +			( n n2 -- n n2' ) \ kernel_state to ASCII num
464
465	s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
466	36 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
467	evaluate	( n c-addr/u -- n ) \ sets $kernel to full kernel-path
468;
469
470: cycle_kernel ( N -- N TRUE )
471	cycle_menuitem	\ cycle cycle_stateN to next value
472	activate_kernel \ apply current cycle_stateN
473	menu-redraw	\ redraw menu
474	TRUE		\ loop menu again
475;
476
477\
478\ Root
479\
480
481: init_root ( N -- N )
482	root_state @    ( n -- n k )
483	init_cyclestate ( n k -- n )
484;
485
486: activate_root ( N -- N )
487	dup cycle_stateN @	( n -- n n2 )
488	dup root_state !	( n n2 -- n n2 )  \ copy for re-initialization
489	48 +			( n n2 -- n n2' ) \ root_state to ASCII num
490
491	s" set root=${root_prefix}${root[N]}${root_suffix}"
492	30 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
493	evaluate	( n c-addr/u -- n ) \ sets $root to full kernel-path
494;
495
496: cycle_root ( N -- N TRUE )
497	cycle_menuitem	\ cycle cycle_stateN to next value
498	activate_root	\ apply current cycle_stateN
499	menu-redraw	\ redraw menu
500	TRUE		\ loop menu again
501;
502
503\
504\ Menusets
505\
506
507: goto_menu ( N M -- N TRUE )
508	menu-unset
509	menuset-loadsetnum ( n m -- n )
510	menu-redraw
511	TRUE \ Loop menu again
512;
513
514\
515\ Defaults
516\
517
518: unset_boot_options
519	0 acpi_state !
520	s" acpi-user-options" unsetenv
521	s" boot-args" unsetenv
522	s" boot_ask" unsetenv
523	singleuser_disable
524	verbose_disable
525	kmdb_disable		\ disables debug as well
526	reconfigure_disable
527;
528
529: set_default_boot_options ( N -- N TRUE )
530	unset_boot_options
531	2 goto_menu
532;
533
534\
535\ Set boot environment defaults
536\
537
538
539: init_bootenv ( -- )
540	s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate
541	s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate
542	s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate
543	s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate
544	s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
545	s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
546;
547
548\
549\ Redraw the entire screen. A long BE name can corrupt the menu
550\
551
552: be_draw_screen
553	clear		\ Clear the screen (in screen.4th)
554	print_version	\ print version string (bottom-right; see version.4th)
555	draw-beastie	\ Draw FreeBSD logo at right (in beastie.4th)
556	draw-brand	\ Draw brand.4th logo at top (in brand.4th)
557	menu-init	\ Initialize menu and draw bounding box (in menu.4th)
558;
559
560\
561\ Select a boot environment
562\
563
564: set_bootenv ( N -- N TRUE )
565	dup s" bootenv_root[E]" 13 +c! getenv
566	s" currdev" getenv compare 0= if
567		s" zfs_be_active" getenv type ."  is already active"
568	else
569		dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate
570		dup s" bootenvmenu_caption[E]" 20 +c! getenv
571		s" zfs_be_active" setenv
572		." Activating " s" currdev" getenv type cr
573		s" unload" evaluate
574		free-module-options
575		unset_boot_options
576		s" /boot/defaults/loader.conf" read-conf
577		s" /boot/loader.conf" read-conf
578		s" /boot/loader.conf.local" read-conf
579		init_bootenv
580
581		s" 1" s" zfs_be_currpage" setenv
582		s" be-set-page" evaluate
583	then
584
585	500 ms			\ sleep so user can see the message
586	be_draw_screen
587	menu-redraw
588	TRUE
589;
590
591\
592\ Chainload this entry. Normally we do not return, in case of error
593\ from chain load, we continue with normal menu code.
594\
595
596: set_be_chain ( N -- no return | N TRUE )
597	dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop
598
599	menu-redraw
600	TRUE
601;
602
603\
604\ Switch to the next page of boot environments
605\
606
607: set_be_page ( N -- N TRUE )
608	s" zfs_be_currpage" getenv dup -1 = if
609		drop s" 1"
610	else
611		0 s>d 2swap
612		>number		( ud caddr/u -- ud' caddr'/u' )
613		2drop
614		1 um/mod	( ud u1 -- u2 u3 )
615		swap drop	( ud2 u3 -- u3 )
616		1+		\ increment the page number
617		dup
618		s" zfs_be_pages" getenv
619		0 s>d 2swap
620		>number		( ud caddr/u -- ud' caddr'/u' )
621		2drop
622		1 um/mod	( ud u1 -- u2 u3 )
623		swap drop	( ud2 u3 -- u3 )
624		> if drop 1 then
625		s>d <# #s #>	\ convert back to a string
626	then
627
628	s" zfs_be_currpage" setenv
629	s" be-set-page" evaluate
630	3 goto_menu
631;
632
633only forth definitions
634