1280937Sdteske\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
2222417Sjulian\ All rights reserved.
3222417Sjulian\ 
4222417Sjulian\ Redistribution and use in source and binary forms, with or without
5222417Sjulian\ modification, are permitted provided that the following conditions
6222417Sjulian\ are met:
7222417Sjulian\ 1. Redistributions of source code must retain the above copyright
8222417Sjulian\    notice, this list of conditions and the following disclaimer.
9222417Sjulian\ 2. Redistributions in binary form must reproduce the above copyright
10222417Sjulian\    notice, this list of conditions and the following disclaimer in the
11222417Sjulian\    documentation and/or other materials provided with the distribution.
12222417Sjulian\ 
13222417Sjulian\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14222417Sjulian\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15222417Sjulian\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16222417Sjulian\ ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17222417Sjulian\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18222417Sjulian\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19222417Sjulian\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20222417Sjulian\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21222417Sjulian\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22222417Sjulian\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23222417Sjulian\ SUCH DAMAGE.
24222417Sjulian\ 
25222417Sjulian\ $FreeBSD: releng/11.0/sys/boot/forth/menu-commands.4th 293001 2015-12-31 20:00:53Z allanjude $
26222417Sjulian
27222417Sjulianmarker task-menu-commands.4th
28222417Sjulian
29242667Sdteskeinclude /boot/menusets.4th
30242667Sdteske
31280937Sdteskeonly forth definitions
32280937Sdteske
33241523Sdteskevariable kernel_state
34241523Sdteskevariable root_state
35257650Sdteske0 kernel_state !
36257650Sdteske0 root_state !
37241523Sdteske
38280937Sdteskealso menu-namespace also menu-command-helpers
39280937Sdteske
40243114Sdteske\ 
41243660Sdteske\ Boot
42243660Sdteske\ 
43243660Sdteske
44243660Sdteske: init_boot ( N -- N )
45243660Sdteske	dup
46243660Sdteske	s" boot_single" getenv -1 <> if
47243660Sdteske		drop ( n n c-addr -- n n ) \ unused
48243660Sdteske		toggle_menuitem ( n n -- n n )
49243660Sdteske		s" set menu_keycode[N]=115" \ base command to execute
50243660Sdteske	else
51243660Sdteske		s" set menu_keycode[N]=98" \ base command to execute
52243660Sdteske	then
53243660Sdteske	17 +c! \ replace 'N' with ASCII numeral
54243660Sdteske	evaluate
55243660Sdteske;
56243660Sdteske
57243660Sdteske\ 
58243660Sdteske\ Alternate Boot
59243660Sdteske\ 
60243660Sdteske
61243660Sdteske: init_altboot ( N -- N )
62243660Sdteske	dup
63243660Sdteske	s" boot_single" getenv -1 <> if
64243660Sdteske		drop ( n c-addr -- n ) \ unused
65243660Sdteske		toggle_menuitem ( n -- n )
66243660Sdteske		s" set menu_keycode[N]=109" \ base command to execute
67243660Sdteske	else
68243660Sdteske		s" set menu_keycode[N]=115" \ base command to execute
69243660Sdteske	then
70243660Sdteske	17 +c! \ replace 'N' with ASCII numeral
71243660Sdteske	evaluate
72243660Sdteske;
73243660Sdteske
74280931Sdteske: altboot ( N -- NOTREACHED )
75243660Sdteske	s" boot_single" 2dup getenv -1 <> if
76243660Sdteske		drop ( c-addr/u c-addr -- c-addr/u ) \ unused
77243660Sdteske		unsetenv ( c-addr/u -- )
78243660Sdteske	else
79243660Sdteske		2drop ( c-addr/u -- ) \ unused
80243660Sdteske		s" set boot_single=YES" evaluate
81243660Sdteske	then
82243660Sdteske	0 boot ( state -- )
83243660Sdteske;
84243660Sdteske
85243660Sdteske\ 
86243114Sdteske\ ACPI
87243114Sdteske\ 
88243114Sdteske
89222417Sjulian: acpi_enable ( -- )
90222417Sjulian	s" set acpi_load=YES" evaluate \ XXX deprecated but harmless
91222417Sjulian	s" set hint.acpi.0.disabled=0" evaluate
92222417Sjulian	s" loader.acpi_disabled_by_user" unsetenv
93222417Sjulian;
94222417Sjulian
95222417Sjulian: acpi_disable ( -- )
96222417Sjulian	s" acpi_load" unsetenv \ XXX deprecated but harmless
97222417Sjulian	s" set hint.acpi.0.disabled=1" evaluate
98222417Sjulian	s" set loader.acpi_disabled_by_user=1" evaluate
99222417Sjulian;
100222417Sjulian
101222417Sjulian: toggle_acpi ( N -- N TRUE )
102222417Sjulian
103222417Sjulian	\ Make changes effective _before_ calling menu-redraw
104222417Sjulian
105222417Sjulian	acpienabled? if
106222417Sjulian		acpi_disable
107222417Sjulian	else
108222417Sjulian		acpi_enable
109222417Sjulian	then
110222417Sjulian
111222417Sjulian	menu-redraw
112222417Sjulian
113222417Sjulian	TRUE \ loop menu again
114222417Sjulian;
115222417Sjulian
116243114Sdteske\ 
117243114Sdteske\ Safe Mode
118243114Sdteske\ 
119243114Sdteske
120243114Sdteske: safemode_enabled? ( -- flag )
121243114Sdteske	s" kern.smp.disabled" getenv -1 <> dup if
122243114Sdteske		swap drop ( c-addr flag -- flag )
123243114Sdteske	then
124243114Sdteske;
125243114Sdteske
126243114Sdteske: safemode_enable ( -- )
127243114Sdteske	s" set kern.smp.disabled=1" evaluate
128243114Sdteske	s" set hw.ata.ata_dma=0" evaluate
129243114Sdteske	s" set hw.ata.atapi_dma=0" evaluate
130243114Sdteske	s" set hw.ata.wc=0" evaluate
131243114Sdteske	s" set hw.eisa_slots=0" evaluate
132243114Sdteske	s" set kern.eventtimer.periodic=1" evaluate
133243114Sdteske	s" set kern.geom.part.check_integrity=0" evaluate
134243114Sdteske;
135243114Sdteske
136243114Sdteske: safemode_disable ( -- )
137243114Sdteske	s" kern.smp.disabled" unsetenv
138243114Sdteske	s" hw.ata.ata_dma" unsetenv
139243114Sdteske	s" hw.ata.atapi_dma" unsetenv
140243114Sdteske	s" hw.ata.wc" unsetenv
141243114Sdteske	s" hw.eisa_slots" unsetenv
142243114Sdteske	s" kern.eventtimer.periodic" unsetenv
143243114Sdteske	s" kern.geom.part.check_integrity" unsetenv
144243114Sdteske;
145243114Sdteske
146241523Sdteske: init_safemode ( N -- N )
147243114Sdteske	safemode_enabled? if
148241523Sdteske		toggle_menuitem ( n -- n )
149241523Sdteske	then
150241523Sdteske;
151241523Sdteske
152222417Sjulian: toggle_safemode ( N -- N TRUE )
153222417Sjulian	toggle_menuitem
154222417Sjulian
155222417Sjulian	\ Now we're going to make the change effective
156222417Sjulian
157243114Sdteske	dup toggle_stateN @ 0= if
158243114Sdteske		safemode_disable
159222417Sjulian	else
160243114Sdteske		safemode_enable
161222417Sjulian	then
162222417Sjulian
163222417Sjulian	menu-redraw
164222417Sjulian
165222417Sjulian	TRUE \ loop menu again
166222417Sjulian;
167222417Sjulian
168243114Sdteske\ 
169243114Sdteske\ Single User Mode
170243114Sdteske\ 
171243114Sdteske
172243114Sdteske: singleuser_enabled? ( -- flag )
173243114Sdteske	s" boot_single" getenv -1 <> dup if
174243114Sdteske		swap drop ( c-addr flag -- flag )
175243114Sdteske	then
176243114Sdteske;
177243114Sdteske
178243114Sdteske: singleuser_enable ( -- )
179243114Sdteske	s" set boot_single=YES" evaluate
180243114Sdteske;
181243114Sdteske
182243114Sdteske: singleuser_disable ( -- )
183243114Sdteske	s" boot_single" unsetenv
184243114Sdteske;
185243114Sdteske
186241523Sdteske: init_singleuser ( N -- N )
187243114Sdteske	singleuser_enabled? if
188241523Sdteske		toggle_menuitem ( n -- n )
189241523Sdteske	then
190241523Sdteske;
191241523Sdteske
192222417Sjulian: toggle_singleuser ( N -- N TRUE )
193222417Sjulian	toggle_menuitem
194222417Sjulian	menu-redraw
195222417Sjulian
196222417Sjulian	\ Now we're going to make the change effective
197222417Sjulian
198243114Sdteske	dup toggle_stateN @ 0= if
199243114Sdteske		singleuser_disable
200222417Sjulian	else
201243114Sdteske		singleuser_enable
202222417Sjulian	then
203222417Sjulian
204222417Sjulian	TRUE \ loop menu again
205222417Sjulian;
206222417Sjulian
207243114Sdteske\ 
208243114Sdteske\ Verbose Boot
209243114Sdteske\ 
210243114Sdteske
211243114Sdteske: verbose_enabled? ( -- flag )
212243114Sdteske	s" boot_verbose" getenv -1 <> dup if
213243114Sdteske		swap drop ( c-addr flag -- flag )
214243114Sdteske	then
215243114Sdteske;
216243114Sdteske
217243114Sdteske: verbose_enable ( -- )
218243114Sdteske	s" set boot_verbose=YES" evaluate
219243114Sdteske;
220243114Sdteske
221243114Sdteske: verbose_disable ( -- )
222243114Sdteske	s" boot_verbose" unsetenv
223243114Sdteske;
224243114Sdteske
225241523Sdteske: init_verbose ( N -- N )
226243114Sdteske	verbose_enabled? if
227241523Sdteske		toggle_menuitem ( n -- n )
228241523Sdteske	then
229241523Sdteske;
230241523Sdteske
231222417Sjulian: toggle_verbose ( N -- N TRUE )
232222417Sjulian	toggle_menuitem
233222417Sjulian	menu-redraw
234222417Sjulian
235222417Sjulian	\ Now we're going to make the change effective
236222417Sjulian
237243114Sdteske	dup toggle_stateN @ 0= if
238243114Sdteske		verbose_disable
239222417Sjulian	else
240243114Sdteske		verbose_enable
241222417Sjulian	then
242222417Sjulian
243222417Sjulian	TRUE \ loop menu again
244222417Sjulian;
245222417Sjulian
246243114Sdteske\ 
247243114Sdteske\ Escape to Prompt
248243114Sdteske\ 
249243114Sdteske
250222417Sjulian: goto_prompt ( N -- N FALSE )
251222417Sjulian
252222417Sjulian	s" set autoboot_delay=NO" evaluate
253222417Sjulian
254222417Sjulian	cr
255222417Sjulian	." To get back to the menu, type `menu' and press ENTER" cr
256222417Sjulian	." or type `boot' and press ENTER to start FreeBSD." cr
257222417Sjulian	cr
258222417Sjulian
259222417Sjulian	FALSE \ exit the menu
260222417Sjulian;
261222417Sjulian
262243114Sdteske\ 
263243114Sdteske\ Cyclestate (used by kernel/root below)
264243114Sdteske\ 
265243114Sdteske
266241523Sdteske: init_cyclestate ( N K -- N )
267243114Sdteske	over cycle_stateN ( n k -- n k addr )
268241523Sdteske	begin
269241523Sdteske		tuck @  ( n k addr -- n addr k c )
270241523Sdteske		over <> ( n addr k c -- n addr k 0|-1 )
271241523Sdteske	while
272241523Sdteske		rot ( n addr k -- addr k n )
273241523Sdteske		cycle_menuitem
274241523Sdteske		swap rot ( addr k n -- n k addr )
275241523Sdteske	repeat
276241523Sdteske	2drop ( n k addr -- n )
277241523Sdteske;
278241523Sdteske
279243114Sdteske\
280243114Sdteske\ Kernel
281243114Sdteske\ 
282243114Sdteske
283241523Sdteske: init_kernel ( N -- N )
284241523Sdteske	kernel_state @  ( n -- n k )
285241523Sdteske	init_cyclestate ( n k -- n )
286241523Sdteske;
287241523Sdteske
288257650Sdteske: activate_kernel ( N -- N )
289257650Sdteske	dup cycle_stateN @	( n -- n n2 )
290257650Sdteske	dup kernel_state !	( n n2 -- n n2 )  \ copy for re-initialization
291257650Sdteske	48 +			( n n2 -- n n2' ) \ kernel_state to ASCII num
292222417Sjulian
293222417Sjulian	s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
294257650Sdteske	36 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
295257650Sdteske	evaluate	( n c-addr/u -- n ) \ sets $kernel to full kernel-path
296257650Sdteske;
297222417Sjulian
298257650Sdteske: cycle_kernel ( N -- N TRUE )
299257650Sdteske	cycle_menuitem	\ cycle cycle_stateN to next value
300257650Sdteske	activate_kernel \ apply current cycle_stateN
301257650Sdteske	menu-redraw	\ redraw menu
302257650Sdteske	TRUE		\ loop menu again
303222417Sjulian;
304222417Sjulian
305243114Sdteske\ 
306243114Sdteske\ Root
307243114Sdteske\ 
308243114Sdteske
309241523Sdteske: init_root ( N -- N )
310241523Sdteske	root_state @    ( n -- n k )
311241523Sdteske	init_cyclestate ( n k -- n )
312241523Sdteske;
313241523Sdteske
314257650Sdteske: activate_root ( N -- N )
315257650Sdteske	dup cycle_stateN @	( n -- n n2 )
316257650Sdteske	dup root_state !	( n n2 -- n n2 )  \ copy for re-initialization
317257650Sdteske	48 +			( n n2 -- n n2' ) \ root_state to ASCII num
318222417Sjulian
319241367Sdteske	s" set root=${root_prefix}${root[N]}${root_suffix}"
320257650Sdteske	30 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
321257650Sdteske	evaluate	( n c-addr/u -- n ) \ sets $root to full kernel-path
322257650Sdteske;
323222417Sjulian
324257650Sdteske: cycle_root ( N -- N TRUE )
325257650Sdteske	cycle_menuitem	\ cycle cycle_stateN to next value
326257650Sdteske	activate_root	\ apply current cycle_stateN
327257650Sdteske	menu-redraw	\ redraw menu
328257650Sdteske	TRUE		\ loop menu again
329222417Sjulian;
330242667Sdteske
331243114Sdteske\ 
332243114Sdteske\ Menusets
333243114Sdteske\ 
334243114Sdteske
335242667Sdteske: goto_menu ( N M -- N TRUE )
336242667Sdteske	menu-unset
337242667Sdteske	menuset-loadsetnum ( n m -- n )
338242667Sdteske	menu-redraw
339242667Sdteske	TRUE \ Loop menu again
340242667Sdteske;
341243660Sdteske
342243660Sdteske\ 
343243660Sdteske\ Defaults
344243660Sdteske\ 
345243660Sdteske
346243660Sdteske: set_default_boot_options ( N -- N TRUE )
347243660Sdteske	acpi_enable
348243660Sdteske	safemode_disable
349243660Sdteske	singleuser_disable
350243660Sdteske	verbose_disable
351243660Sdteske	2 goto_menu
352243660Sdteske;
353280937Sdteske
354293001Sallanjude\ 
355293001Sallanjude\ Set boot environment defaults
356293001Sallanjude\ 
357293001Sallanjude
358293001Sallanjude: init_bootenv ( -- )
359293001Sallanjude	s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate
360293001Sallanjude	s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate
361293001Sallanjude	s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate
362293001Sallanjude	s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate
363293001Sallanjude	s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
364293001Sallanjude	s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
365293001Sallanjude;
366293001Sallanjude
367293001Sallanjude\
368293001Sallanjude\ Redraw the entire screen. A long BE name can corrupt the menu
369293001Sallanjude\ 
370293001Sallanjude
371293001Sallanjude: be_draw_screen
372293001Sallanjude	clear		\ Clear the screen (in screen.4th)
373293001Sallanjude	print_version	\ print version string (bottom-right; see version.4th)
374293001Sallanjude	draw-beastie	\ Draw FreeBSD logo at right (in beastie.4th)
375293001Sallanjude	draw-brand	\ Draw brand.4th logo at top (in brand.4th)
376293001Sallanjude	menu-init	\ Initialize menu and draw bounding box (in menu.4th)
377293001Sallanjude;
378293001Sallanjude
379293001Sallanjude\
380293001Sallanjude\ Select a boot environment
381293001Sallanjude\ 
382293001Sallanjude
383293001Sallanjude: set_bootenv ( N -- N TRUE )
384293001Sallanjude	dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate
385293001Sallanjude	s" set currdev=${vfs.root.mountfrom}:" evaluate
386293001Sallanjude	s" unload" evaluate
387293001Sallanjude	free-module-options
388293001Sallanjude	s" /boot/defaults/loader.conf" read-conf
389293001Sallanjude	s" /boot/loader.conf" read-conf
390293001Sallanjude	s" /boot/loader.conf.local" read-conf
391293001Sallanjude	init_bootenv
392293001Sallanjude	be_draw_screen
393293001Sallanjude	menu-redraw
394293001Sallanjude	TRUE
395293001Sallanjude;
396293001Sallanjude
397293001Sallanjude\
398293001Sallanjude\ Switch to the next page of boot environments
399293001Sallanjude\
400293001Sallanjude
401293001Sallanjude: set_be_page ( N -- N TRUE )
402293001Sallanjude	s" zfs_be_currpage" getenv dup -1 = if
403293001Sallanjude		drop s" 1"
404293001Sallanjude	else
405293001Sallanjude		0 s>d 2swap
406293001Sallanjude		>number ( ud caddr/u -- ud' caddr'/u' )	\ convert string to numbers
407293001Sallanjude		2drop					\ drop the string
408293001Sallanjude		1 um/mod ( ud u1 -- u2 u3 ) 		\ convert double ud' to single u3' and remainder u2
409293001Sallanjude		swap drop ( ud2 u3 -- u3 )		\ drop the remainder u2
410293001Sallanjude		1+					\ increment the page number
411293001Sallanjude		s>d <# #s #>				\ convert back to a string
412293001Sallanjude	then
413293001Sallanjude	s" zfs_be_currpage" setenv
414293001Sallanjude	s" reloadbe" evaluate
415293001Sallanjude	3 goto_menu
416293001Sallanjude;
417293001Sallanjude
418280937Sdteskeonly forth definitions
419