summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-29 00:59:38 +0000
committerattilio <attilio@FreeBSD.org>2011-05-29 00:59:38 +0000
commit55a3bf38a5f8f3d517542f92fc9e34a1cebcce52 (patch)
tree19a91bf94ba6b6dca19c88849791de347e024692 /sys
parenteefddaeed6c0577102de6360a326fa15c36afd07 (diff)
parent16f4172df58aff2531075ad9428e980aba6a25bd (diff)
downloadFreeBSD-src-55a3bf38a5f8f3d517542f92fc9e34a1cebcce52.zip
FreeBSD-src-55a3bf38a5f8f3d517542f92fc9e34a1cebcce52.tar.gz
MFC
Diffstat (limited to 'sys')
-rw-r--r--sys/boot/common/Makefile.inc7
-rw-r--r--sys/boot/forth/beastie.4th423
-rw-r--r--sys/boot/forth/beastie.4th.8171
-rw-r--r--sys/boot/forth/brand.4th91
-rw-r--r--sys/boot/forth/brand.4th.8125
-rw-r--r--sys/boot/forth/check-password.4th156
-rw-r--r--sys/boot/forth/check-password.4th.8123
-rw-r--r--sys/boot/forth/color.4th48
-rw-r--r--sys/boot/forth/color.4th.8117
-rw-r--r--sys/boot/forth/delay.4th112
-rw-r--r--sys/boot/forth/delay.4th.8126
-rw-r--r--sys/boot/forth/loader.4th25
-rw-r--r--sys/boot/forth/loader.conf.58
-rw-r--r--sys/boot/forth/loader.rc5
-rw-r--r--sys/boot/forth/menu-commands.4th190
-rw-r--r--sys/boot/forth/menu.4th971
-rw-r--r--sys/boot/forth/menu.4th.8307
-rw-r--r--sys/boot/forth/menu.rc76
-rw-r--r--sys/boot/forth/shortcuts.4th50
-rw-r--r--sys/boot/forth/support.4th33
-rw-r--r--sys/boot/forth/version.4th60
-rw-r--r--sys/boot/forth/version.4th.8126
-rw-r--r--sys/boot/i386/loader/Makefile5
-rw-r--r--sys/boot/ia64/common/Makefile5
-rw-r--r--sys/boot/pc98/loader/Makefile6
-rw-r--r--sys/boot/powerpc/ofw/Makefile6
-rw-r--r--sys/boot/powerpc/ps3/Makefile6
-rw-r--r--sys/boot/sparc64/loader/Makefile6
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_attach.c5
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.c1
-rw-r--r--sys/dev/ath/if_ath.c17
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c19
-rw-r--r--sys/fs/nfs/nfs_var.h4
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c2
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c94
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c6
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c18
-rw-r--r--sys/kern/kern_racct.c5
-rw-r--r--sys/kern/kern_rctl.c2
-rw-r--r--sys/powerpc/booke/locore.S68
-rw-r--r--sys/powerpc/booke/machdep.c53
-rw-r--r--sys/powerpc/booke/platform_bare.c51
-rw-r--r--sys/powerpc/booke/pmap.c25
-rw-r--r--sys/powerpc/include/param.h2
-rw-r--r--sys/powerpc/include/spr.h4
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx.c21
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx.h5
-rw-r--r--sys/powerpc/powermac/powermac_thermal.c176
-rw-r--r--sys/powerpc/powermac/powermac_thermal.h54
-rw-r--r--sys/powerpc/powermac/smu.c199
-rw-r--r--sys/powerpc/powermac/smusat.c50
-rw-r--r--sys/sys/racct.h40
-rw-r--r--sys/ufs/ffs/ffs_alloc.c2
54 files changed, 3695 insertions, 613 deletions
diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc
index 9893278..be6c3301 100644
--- a/sys/boot/common/Makefile.inc
+++ b/sys/boot/common/Makefile.inc
@@ -44,8 +44,15 @@ SRCS+= pnp.c
# Forth interpreter
.if defined(BOOT_FORTH)
SRCS+= interp_forth.c
+MAN+= ../forth/beastie.4th.8
+MAN+= ../forth/brand.4th.8
+MAN+= ../forth/check-password.4th.8
+MAN+= ../forth/color.4th.8
+MAN+= ../forth/delay.4th.8
MAN+= ../forth/loader.conf.5
MAN+= ../forth/loader.4th.8
+MAN+= ../forth/menu.4th.8
+MAN+= ../forth/version.4th.8
.endif
.if defined(BOOT_PROMPT_123)
diff --git a/sys/boot/forth/beastie.4th b/sys/boot/forth/beastie.4th
index 1130ed0..75d6e02 100644
--- a/sys/boot/forth/beastie.4th
+++ b/sys/boot/forth/beastie.4th
@@ -1,7 +1,8 @@
\ Copyright (c) 2003 Scott Long <scottl@freebsd.org>
\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
\ All rights reserved.
-\
+\
\ Redistribution and use in source and binary forms, with or without
\ modification, are permitted provided that the following conditions
\ are met:
@@ -10,7 +11,7 @@
\ 2. Redistributions in binary form must reproduce the above copyright
\ notice, this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
-\
+\
\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -22,35 +23,24 @@
\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
-\
+\
\ $FreeBSD$
marker task-beastie.4th
-include /boot/screen.4th
-include /boot/frames.4th
+include /boot/color.4th
+include /boot/delay.4th
-hide
+variable logoX
+variable logoY
-variable menuidx
-variable menubllt
-variable menuX
-variable menuY
-variable promptwidth
+\ Initialize logo placement to defaults
+46 logoX !
+4 logoY !
-variable bootkey
-variable bootacpikey
-variable bootsafekey
-variable bootverbosekey
-variable bootsinglekey
-variable escapekey
-variable rebootkey
+: beastie-logo ( x y -- ) \ color BSD mascot (19 rows x 34 columns)
-46 constant dot
-
-\ The BSD Daemon. He is 19 rows high and 34 columns wide
-: beastie-logo ( x y -- )
-2dup at-xy ." , ," 1+
+2dup at-xy ." , ," 1+
2dup at-xy ." /( )`" 1+
2dup at-xy ." \ \___ / |" 1+
2dup at-xy ." /- _ `-/ '" 1+
@@ -59,7 +49,7 @@ variable rebootkey
2dup at-xy ." O O ) / |" 1+
2dup at-xy ." `-^--'`< '" 1+
2dup at-xy ." (_.) _ ) /" 1+
-2dup at-xy ." `.___/` / " 1+
+2dup at-xy ." `.___/` /" 1+
2dup at-xy ." `-----' /" 1+
2dup at-xy ." <----. __ / __ \" 1+
2dup at-xy ." <----|====O)))==) \) /====|" 1+
@@ -68,173 +58,201 @@ variable rebootkey
2dup at-xy ." \ / /\" 1+
2dup at-xy ." ______( (_ / \______/" 1+
2dup at-xy ." ,' ,-----' |" 1+
-at-xy ." `--{__________) "
+ at-xy ." `--{__________)"
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
;
-: beastiebw-logo ( x y -- )
- 2dup at-xy ." , ," 1+
- 2dup at-xy ." /( )`" 1+
- 2dup at-xy ." \ \___ / |" 1+
- 2dup at-xy ." /- _ `-/ '" 1+
- 2dup at-xy ." (/\/ \ \ /\" 1+
- 2dup at-xy ." / / | ` \" 1+
- 2dup at-xy ." O O ) / |" 1+
- 2dup at-xy ." `-^--'`< '" 1+
- 2dup at-xy ." (_.) _ ) /" 1+
- 2dup at-xy ." `.___/` /" 1+
- 2dup at-xy ." `-----' /" 1+
- 2dup at-xy ." <----. __ / __ \" 1+
- 2dup at-xy ." <----|====O)))==) \) /====" 1+
- 2dup at-xy ." <----' `--' `.__,' \" 1+
- 2dup at-xy ." | |" 1+
- 2dup at-xy ." \ / /\" 1+
- 2dup at-xy ." ______( (_ / \______/" 1+
- 2dup at-xy ." ,' ,-----' |" 1+
- at-xy ." `--{__________)"
+: beastiebw-logo ( x y -- ) \ B/W BSD mascot (19 rows x 34 columns)
+
+ 2dup at-xy ." , ," 1+
+ 2dup at-xy ." /( )`" 1+
+ 2dup at-xy ." \ \___ / |" 1+
+ 2dup at-xy ." /- _ `-/ '" 1+
+ 2dup at-xy ." (/\/ \ \ /\" 1+
+ 2dup at-xy ." / / | ` \" 1+
+ 2dup at-xy ." O O ) / |" 1+
+ 2dup at-xy ." `-^--'`< '" 1+
+ 2dup at-xy ." (_.) _ ) /" 1+
+ 2dup at-xy ." `.___/` /" 1+
+ 2dup at-xy ." `-----' /" 1+
+ 2dup at-xy ." <----. __ / __ \" 1+
+ 2dup at-xy ." <----|====O)))==) \) /====|" 1+
+ 2dup at-xy ." <----' `--' `.__,' \" 1+
+ 2dup at-xy ." | |" 1+
+ 2dup at-xy ." \ / /\" 1+
+ 2dup at-xy ." ______( (_ / \______/" 1+
+ 2dup at-xy ." ,' ,-----' |" 1+
+ at-xy ." `--{__________)"
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
;
-: fbsdbw-logo ( x y -- )
- 2dup at-xy ." ______" 1+
- 2dup at-xy ." | ____| __ ___ ___ " 1+
- 2dup at-xy ." | |__ | '__/ _ \/ _ \" 1+
- 2dup at-xy ." | __|| | | __/ __/" 1+
- 2dup at-xy ." | | | | | | |" 1+
- 2dup at-xy ." |_| |_| \___|\___|" 1+
- 2dup at-xy ." ____ _____ _____" 1+
- 2dup at-xy ." | _ \ / ____| __ \" 1+
- 2dup at-xy ." | |_) | (___ | | | |" 1+
- 2dup at-xy ." | _ < \___ \| | | |" 1+
- 2dup at-xy ." | |_) |____) | |__| |" 1+
- 2dup at-xy ." | | | |" 1+
- at-xy ." |____/|_____/|_____/"
+: fbsdbw-logo ( x y -- ) \ "FreeBSD" logo in B/W (13 rows x 21 columns)
+
+ \ We used to use the beastie himself as our default... until the
+ \ eventual complaint derided his reign of the advanced boot-menu.
+ \
+ \ This is the replacement of beastie to satiate the haters of our
+ \ beloved helper-daemon (ready to track down and spear bugs with
+ \ his trident and sporty sneakers; see above).
+ \
+ \ Since we merely just changed the default and not the default-
+ \ location, below is an adjustment to the passed-in coordinates,
+ \ forever influenced by the proper location of beastie himself
+ \ kept as the default loader_logo_x/loader_logo_y values.
+ \
+ 5 + swap 6 + swap
+
+ 2dup at-xy ." ______" 1+
+ 2dup at-xy ." | ____| __ ___ ___ " 1+
+ 2dup at-xy ." | |__ | '__/ _ \/ _ \" 1+
+ 2dup at-xy ." | __|| | | __/ __/" 1+
+ 2dup at-xy ." | | | | | | |" 1+
+ 2dup at-xy ." |_| |_| \___|\___|" 1+
+ 2dup at-xy ." ____ _____ _____" 1+
+ 2dup at-xy ." | _ \ / ____| __ \" 1+
+ 2dup at-xy ." | |_) | (___ | | | |" 1+
+ 2dup at-xy ." | _ < \___ \| | | |" 1+
+ 2dup at-xy ." | |_) |____) | |__| |" 1+
+ 2dup at-xy ." | | | |" 1+
+ at-xy ." |____/|_____/|_____/"
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
;
-: print-logo ( x y -- )
- s" loader_logo" getenv
- dup -1 = if
- drop
- fbsdbw-logo
- exit
- then
- 2dup s" fbsdbw" compare-insensitive 0= if
- 2drop
- fbsdbw-logo
- exit
- then
- 2dup s" beastiebw" compare-insensitive 0= if
- 2drop
- beastiebw-logo
- exit
- then
- 2dup s" beastie" compare-insensitive 0= if
- 2drop
- beastie-logo
- exit
- then
- 2dup s" none" compare-insensitive 0= if
- 2drop
- \ no logo
- exit
- then
- 2drop
- fbsdbw-logo
+: orb-logo ( x y -- ) \ color Orb mascot (15 rows x 30 columns)
+
+ 3 + \ beastie adjustment (see `fbsdbw-logo' comments above)
+
+ 2dup at-xy ." ``` `" 1+
+ 2dup at-xy ." s` `.....---.......--.``` -/" 1+
+ 2dup at-xy ." +o .--` /y:` +." 1+
+ 2dup at-xy ." yo`:. :o `+-" 1+
+ 2dup at-xy ." y/ -/` -o/" 1+
+ 2dup at-xy ." .- ::/sy+:." 1+
+ 2dup at-xy ." / `-- /" 1+
+ 2dup at-xy ." `: :`" 1+
+ 2dup at-xy ." `: :`" 1+
+ 2dup at-xy ." / /" 1+
+ 2dup at-xy ." .- -." 1+
+ 2dup at-xy ." -- -." 1+
+ 2dup at-xy ." `:` `:`" 1+
+ 2dup at-xy ." .-- `--." 1+
+ at-xy ." .---.....----."
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
;
-: acpipresent? ( -- flag )
- s" hint.acpi.0.rsdp" getenv
- dup -1 = if
- drop false exit
- then
- 2drop
- true
+: orbbw-logo ( x y -- ) \ B/W Orb mascot (15 rows x 32 columns)
+
+ 3 + \ beastie adjustment (see `fbsdbw-logo' comments above)
+
+ 2dup at-xy ." ``` `" 1+
+ 2dup at-xy ." s` `.....---.......--.``` -/" 1+
+ 2dup at-xy ." +o .--` /y:` +." 1+
+ 2dup at-xy ." yo`:. :o `+-" 1+
+ 2dup at-xy ." y/ -/` -o/" 1+
+ 2dup at-xy ." .- ::/sy+:." 1+
+ 2dup at-xy ." / `-- /" 1+
+ 2dup at-xy ." `: :`" 1+
+ 2dup at-xy ." `: :`" 1+
+ 2dup at-xy ." / /" 1+
+ 2dup at-xy ." .- -." 1+
+ 2dup at-xy ." -- -." 1+
+ 2dup at-xy ." `:` `:`" 1+
+ 2dup at-xy ." .-- `--." 1+
+ at-xy ." .---.....----."
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
;
-: acpienabled? ( -- flag )
- s" hint.acpi.0.disabled" getenv
- dup -1 <> if
- s" 0" compare 0<> if
- false exit
- then
+\ This function draws any number of beastie logos at (loader_logo_x,
+\ loader_logo_y) if defined, else (46,4) (to the right of the menu). To choose
+\ your beastie, set the variable `loader_logo' to the respective logo name.
+\
+\ Currently available:
+\
+\ NAME DESCRIPTION
+\ beastie Color ``Helper Daemon'' mascot (19 rows x 34 columns)
+\ beastiebw B/W ``Helper Daemon'' mascot (19 rows x 34 columns)
+\ fbsdbw "FreeBSD" logo in B/W (13 rows x 21 columns)
+\ orb Color ``Orb'' mascot (15 rows x 30 columns)
+\ orbbw B/W ``Orb'' mascot (15 rows x 32 columns) (default)
+\
+\ NOTE: Setting `loader_logo' to an undefined value (such as "none") will
+\ prevent beastie from being drawn.
+\
+: draw-beastie ( -- ) \ at (loader_logo_x,loader_logo_y), else (46,4)
+
+ s" loader_logo_x" getenv dup -1 <> if
+ ?number 1 = if logoX ! then
else
drop
then
- true
-;
-
-: printmenuitem ( -- n )
- menuidx @
- 1+ dup
- menuidx !
- menuY @ + dup menuX @ swap at-xy
- menuidx @ .
- menuX @ 1+ swap at-xy
- menubllt @ emit
- menuidx @ 48 +
-;
-
-: beastie-menu ( -- )
- 0 menuidx !
- dot menubllt !
- 8 menuY !
- 5 menuX !
- clear
- 46 4 print-logo
- 42 20 2 2 box
- 13 6 at-xy ." Welcome to FreeBSD!"
- printmenuitem ." Boot FreeBSD [default]" bootkey !
- s" arch-i386" environment? if
+ s" loader_logo_y" getenv dup -1 <> if
+ ?number 1 = if logoY ! then
+ else
drop
- acpipresent? if
- printmenuitem ." Boot FreeBSD with ACPI " bootacpikey !
- acpienabled? if
- ." disabled"
- else
- ." enabled"
- then
+ then
+
+ s" loader_logo" getenv dup -1 = if
+ logoX @ logoY @
+ loader_color? if
+ orb-logo
else
- menuidx @
- 1+
- menuidx !
- -2 bootacpikey !
+ orbbw-logo
then
- else
- -2 bootacpikey !
+ drop exit
then
- printmenuitem ." Boot FreeBSD in Safe Mode" bootsafekey !
- printmenuitem ." Boot FreeBSD in single user mode" bootsinglekey !
- printmenuitem ." Boot FreeBSD with verbose logging" bootverbosekey !
- printmenuitem ." Escape to loader prompt" escapekey !
- printmenuitem ." Reboot" rebootkey !
- menuX @ 20 at-xy
- ." Select option, [Enter] for default"
- menuX @ 21 at-xy
- s" or [Space] to pause timer " dup 2 - promptwidth !
- type
-;
-: tkey
- seconds +
- begin 1 while
- over 0<> if
- dup seconds u< if
- drop
- -1
- exit
- then
- menuX @ promptwidth @ + 21 at-xy dup seconds - .
- then
- key? if
- drop
- key
- exit
- then
- 50 ms
- repeat
+ 2dup s" beastie" compare-insensitive 0= if
+ logoX @ logoY @ beastie-logo
+ 2drop exit
+ then
+ 2dup s" beastiebw" compare-insensitive 0= if
+ logoX @ logoY @ beastiebw-logo
+ 2drop exit
+ then
+ 2dup s" fbsdbw" compare-insensitive 0= if
+ logoX @ logoY @ fbsdbw-logo
+ 2drop exit
+ then
+ 2dup s" orb" compare-insensitive 0= if
+ logoX @ logoY @ orb-logo
+ 2drop exit
+ then
+ 2dup s" orbbw" compare-insensitive 0= if
+ logoX @ logoY @ orbbw-logo
+ 2drop exit
+ then
+
+ 2drop
;
-set-current
+: clear-beastie ( -- ) \ clears beastie from the screen
+ logoX @ logoY @
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 1+ 2dup at-xy 34 spaces 1+
+ 2dup at-xy 34 spaces 2drop
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
+;
-: beastie-start
+: beastie-start ( -- ) \ starts the menu
s" beastie_disable" getenv
dup -1 <> if
s" YES" compare-insensitive 0= if
@@ -243,62 +261,15 @@ set-current
else
drop
then
- beastie-menu
- s" autoboot_delay" getenv
- dup -1 = if
- drop
- 10
+
+ s" loader_delay" getenv
+ -1 = if
+ s" include /boot/menu.rc" evaluate
else
- 2dup s" -1" compare 0= if
- 0 boot
- then
- 0 s>d 2swap >number 2drop drop
+ drop
+ ." Loading Menu (Ctrl-C to Abort)" cr
+ s" set delay_command='include /boot/menu.rc'" evaluate
+ s" set delay_showdots" evaluate
+ delay_execute
then
- begin
- dup tkey
- 0 25 at-xy
- dup 32 = if nip 0 swap then
- dup -1 = if 0 boot then
- dup 13 = if 0 boot then
- dup bootkey @ = if 0 boot then
- dup bootacpikey @ = if
- acpienabled? if
- s" 1" s" hint.acpi.0.disabled" setenv
- s" 1" s" loader.acpi_disabled_by_user" setenv
- else
- s" 0" s" hint.acpi.0.disabled" setenv
- then
- 0 boot
- then
- dup bootsafekey @ = if
- s" arch-i386" environment? if
- drop
- s" 1" s" hint.acpi.0.disabled" setenv
- s" 1" s" loader.acpi_disabled_by_user" setenv
- s" 1" s" hint.apic.0.disabled" setenv
- then
- s" 0" s" hw.ata.ata_dma" setenv
- s" 0" s" hw.ata.atapi_dma" setenv
- s" 0" s" hw.ata.wc" setenv
- s" 0" s" hw.eisa_slots" setenv
- s" 1" s" hint.kbdmux.0.disabled" setenv
- 0 boot
- then
- dup bootverbosekey @ = if
- s" YES" s" boot_verbose" setenv
- 0 boot
- then
- dup bootsinglekey @ = if
- s" YES" s" boot_single" setenv
- 0 boot
- then
- dup escapekey @ = if
- 2drop
- s" NO" s" autoboot_delay" setenv
- exit
- then
- rebootkey @ = if 0 reboot then
- again
;
-
-previous
diff --git a/sys/boot/forth/beastie.4th.8 b/sys/boot/forth/beastie.4th.8
new file mode 100644
index 0000000..5108769
--- /dev/null
+++ b/sys/boot/forth/beastie.4th.8
@@ -0,0 +1,171 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 16, 2011
+.Dt BEASTIE.4TH 8
+.Os
+.Sh NAME
+.Nm beastie.4th
+.Nd FreeBSD ASCII art boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the ASCII art FreeBSD mascot
+.Nd known simply as
+.Ic beastie
+.Nd to the right of the boot loader menu.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include beastie.4th
+.Pp
+This line is present in the default
+.Pa /boot/loader.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic draw-beastie
+Draws the FreeBSD logo.
+.Pp
+The logo that is drawn is configured by setting the
+.Ic loader_logo
+variable in
+.Xr loader.conf 5
+to one of
+.Dq Li beastie ,
+.Dq Li beastiebw ,
+.Dq Li fbsdbw ,
+.Dq Li orb ,
+and
+.Dq Li orbbw
+(the default).
+.Pp
+The position of the logo can be configured by setting the
+.Ic loader_logo_x
+and
+.Ic loader_logo_y
+variables in
+.Xr loader.conf 5 .
+The default values are 46 (x) and 4 (y).
+.Pp
+.It Ic clear-beastie
+Clears the screen of beastie.
+.Pp
+.It Ic beastie-start
+Initializes the interactive boot loader menu.
+.Pp
+The
+.Ic loader_delay
+variable can be configured in
+.Xr loader.conf 5
+to the number of seconds you would like to delay loading the boot menu.
+During the delay the user can press Ctrl-C to fall back to autoboot or ENTER
+to proceed.
+The default behavior is to not delay.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_logo
+Selects the desired logo in the beastie boot menu. Possible values are:
+.Dq Li fbsdbw ,
+.Dq Li beastie ,
+.Dq Li beastiebw ,
+.Dq Li orb ,
+.Dq Li orbbw
+(default), and
+.Dq Li none .
+.It Va loader_logo_x
+Sets the desired column position of the logo. Default is 46.
+.It Va loader_logo_y
+Sets the desired row position of the logo. Default is 4.
+.It Va beastie_disable
+If set to
+.Dq YES ,
+the beastie boot menu will be skipped.
+.It Va loader_delay
+If set to a number higher than zero, introduces a delay before starting the
+beastie boot menu. During the delay the user can press either Ctrl-C to skip
+the menu or ENTER to proceed to the menu. The default is to not delay when
+loading the menu.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/beastie.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/beastie.4th
+beastie-start
+.Ed
+.Pp
+Set a different logo in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_logo="beastie"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 5.1 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Scott Long Aq scottl@FreeBSD.org ,
+.An Aleksander Fafula Aq alex@fafula.com
+and
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/brand.4th b/sys/boot/forth/brand.4th
new file mode 100644
index 0000000..bc64174
--- /dev/null
+++ b/sys/boot/forth/brand.4th
@@ -0,0 +1,91 @@
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-brand.4th
+
+variable brandX
+variable brandY
+
+\ Initialize logo placement
+2 brandX !
+1 brandY !
+
+: fbsd-logo ( x y -- ) \ "FreeBSD" [wide] logo in B/W (7 rows x 42 columns)
+
+ 2dup at-xy ." ______ ____ _____ _____ " 1+
+ 2dup at-xy ." | ____| | _ \ / ____| __ \ " 1+
+ 2dup at-xy ." | |___ _ __ ___ ___ | |_) | (___ | | | |" 1+
+ 2dup at-xy ." | ___| '__/ _ \/ _ \| _ < \___ \| | | |" 1+
+ 2dup at-xy ." | | | | | __/ __/| |_) |____) | |__| |" 1+
+ 2dup at-xy ." | | | | | | || | | |" 1+
+ at-xy ." |_| |_| \___|\___||____/|_____/|_____/ "
+
+ \ Put the cursor back at the bottom
+ 0 25 at-xy
+;
+
+\ This function draws any number of company logos at (loader_brand_x,
+\ loader_brand_y) if defined, or (2,1) (top-left) if not defined. To choose
+\ your logo, set the variable `loader_brand' to the respective logo name.
+\
+\ Currently available:
+\
+\ NAME DESCRIPTION
+\ fbsd FreeBSD logo
+\
+\ NOTE: Setting `loader_brand' to an undefined value (such as "none") will
+\ prevent any brand from being drawn.
+\
+: draw-brand ( -- )
+
+ s" loader_brand_x" getenv dup -1 <> if
+ ?number 1 = if
+ brandX !
+ then
+ else
+ drop
+ then
+
+ s" loader_brand_y" getenv dup -1 <> if
+ ?number 1 = if
+ brandY !
+ then
+ else
+ drop
+ then
+
+ s" loader_brand" getenv dup -1 = if
+ brandX @ brandY @ fbsd-logo
+ drop exit
+ then
+
+ 2dup s" fbsd" compare-insensitive 0= if
+ brandX @ brandY @ fbsd-logo
+ 2drop exit
+ then
+
+ 2drop
+;
diff --git a/sys/boot/forth/brand.4th.8 b/sys/boot/forth/brand.4th.8
new file mode 100644
index 0000000..1a1cc84
--- /dev/null
+++ b/sys/boot/forth/brand.4th.8
@@ -0,0 +1,125 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt BRAND.4TH 8
+.Os
+.Sh NAME
+.Nm brand.4th
+.Nd FreeBSD ASCII art boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the ASCII art BSD brand above the boot
+loader menu.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include brand.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic draw-brand
+Draws the BSD brand.
+.Pp
+The brand that is drawn is configured by setting the
+.Ic loader_brand
+variable in
+.Xr loader.conf 5
+to one of
+.Dq Li fbsd
+(the default) or
+.Dq Li none .
+.Pp
+The position of the logo can be configured by setting the
+.Ic loader_brand_x
+and
+.Ic loader_brand_y
+variables in
+.Xr loader.conf 5 .
+The default values are 2 (x) and 1 (y).
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_brand
+Selects the desired brand in the beastie boot menu. Possible values are:
+.Dq Li fbsd
+(default) or
+.Dq Li none .
+.It Va loader_brand_x
+Sets the desired column position of the brand. Default is 2.
+.It Va loader_brand_y
+Sets the desired row position of the brand. Default is 1.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/brand.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Set FreeBSD brand in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_brand="fbsd"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/check-password.4th b/sys/boot/forth/check-password.4th
new file mode 100644
index 0000000..0a1fa5d
--- /dev/null
+++ b/sys/boot/forth/check-password.4th
@@ -0,0 +1,156 @@
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-check-password.4th
+
+include /boot/screen.4th
+
+13 constant enter_key \ The decimal ASCII value for Enter key
+8 constant bs_key \ The decimal ASCII value for Backspace key
+16 constant readmax \ Maximum number of characters for the password
+
+variable readX \ Current X offset (column)(used by read)
+variable read-start \ Starting X offset (column)(used by read)
+
+create readval 16 allot \ input obtained (maximum 16 characters)
+variable readlen \ input length
+
+\ This function blocks program flow (loops forever) until a key is pressed.
+\ The key that was pressed is added to the top of the stack in the form of its
+\ decimal ASCII representation. Note: the stack cannot be empty when this
+\ function starts or an underflow exception will occur. Simplest way to prevent
+\ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
+\ called by the read function. You need not call it directly. NOTE: arrow keys
+\ show as 0 on the stack
+\
+: sgetkey ( -- )
+
+ begin \ Loop forever
+ key? if \ Was a key pressed? (see loader(8))
+
+ drop \ Remove stack-cruft
+ key \ Get the key that was pressed
+
+ \ Check key pressed (see loader(8)) and input limit
+ dup 0<> if ( and ) readlen @ readmax < if
+
+ \ Echo an asterisk (unless Backspace/Enter)
+ dup bs_key <> if ( and ) dup enter_key <> if
+ ." *" \ Echo an asterisk
+ then then
+
+ exit \ Exit from the function
+ then then
+
+ \ Always allow Backspace and Enter
+ dup bs_key = if exit then
+ dup enter_key = if exit then
+
+ then
+ 50 ms \ Sleep for 50 milliseconds (see loader(8))
+ again
+;
+
+: read ( -- String prompt )
+
+ 0 25 at-xy \ Move the cursor to the bottom-left
+ dup 1+ read-start ! \ Store X offset after the prompt
+ read-start @ readX ! \ copy value to the current X offset
+ 0 readlen ! \ Initialize the read length
+ type \ Print the prompt
+
+ begin \ Loop forever
+
+ 0 sgetkey \ Block here, waiting for a key to be pressed
+
+ \ We are not going to echo the password to the screen (for
+ \ security reasons). If Enter is pressed, we process the
+ \ password, otherwise augment the key to a string.
+
+ \ If the key that was entered was not Enter, advance
+ dup enter_key <> if
+ readX @ 1+ readX ! \ Advance the column
+ readlen @ 1+ readlen ! \ Increment input length
+ then
+
+ \ Handle backspacing
+ dup bs_key = if
+ readX @ 2 - readX ! \ Set new cursor position
+ readlen @ 2 - readlen ! \ Decrement input length
+
+ \ Don't move behind starting position
+ readX @ read-start @ < if
+ read-start @ readX !
+ then
+ readlen @ 0< if
+ 0 readlen !
+ then
+
+ \ Reposition cursor and erase character
+ readX @ 25 at-xy 1 spaces readX @ 25 at-xy
+ then
+
+ dup enter_key = if
+ drop \ Clean up stack cruft
+ 10 emit \ Echo new line
+ exit
+ then
+
+ \ If not Backspace or Enter, store the character
+ dup bs_key <> if ( and ) dup enter_key <> if
+
+ \ store the character in our buffer
+ dup readval readlen @ 1- + c!
+
+ then then
+
+ drop \ drop the last key that was entered
+
+ again \ Enter was not pressed; repeat
+;
+
+: check-password ( -- )
+
+ \ Exit if a password was not set
+ s" password" getenv dup -1 = if
+ drop exit
+ then
+
+ begin \ Loop as long as it takes to get the right password
+
+ s" Password: " \ Output a prompt for a password
+ read \ Read the user's input until Enter
+
+ 2dup readval readlen @ compare 0= if
+ 2drop exit \ Correct password
+ then
+
+ \ Bad Password
+ 3000 ms
+ ." loader: incorrect password" 10 emit
+
+ again \ Not the right password; repeat
+;
diff --git a/sys/boot/forth/check-password.4th.8 b/sys/boot/forth/check-password.4th.8
new file mode 100644
index 0000000..95b2654
--- /dev/null
+++ b/sys/boot/forth/check-password.4th.8
@@ -0,0 +1,123 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt CHECK-PASSWORD.4TH 8
+.Os
+.Sh NAME
+.Nm check-password.4th
+.Nd FreeBSD password-checking boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to prevent booting without the proper password.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include check-password.4th
+.Pp
+This line is present in
+.Pa /boot/loader.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic check-password
+Once called, the user cannot continue until the correct password is entered.
+If the user enters the correct password the function returns.
+.Pp
+The password that is required is configured by setting the
+.Ic password
+variable in
+.Xr loader.conf 5 .
+.Pp
+Subsequent calls after a successful password
+has been entered will not cause reprompting
+.Nd the function will silently return.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va password
+Sets the password (up to 16 characters long) that is required by
+.Ic check-password
+to be entered before the system is allowed to boot. If unset (default) or NULL,
+.Ic check-password
+will silently abort.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/check-password.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/loader.4th
+check-password
+.Ed
+.Pp
+Set a password in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+password="abc123"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/color.4th b/sys/boot/forth/color.4th
new file mode 100644
index 0000000..4d43593
--- /dev/null
+++ b/sys/boot/forth/color.4th
@@ -0,0 +1,48 @@
+\ Copyright (c) 2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-color.4th
+
+\ This function returns TRUE if the `loader_color' environment variable is set
+\ to YES, yes, or 1. Otherwise, FALSE is returned.
+\
+: loader_color? ( -- N )
+
+ s" loader_color" getenv dup -1 <> if
+
+ 2dup s" YES" compare-insensitive 0= if
+ 2drop
+ TRUE exit
+ then
+ 2dup s" 1" compare 0= if
+ 2drop
+ TRUE exit
+ then
+ drop
+ then
+
+ drop FALSE exit
+;
diff --git a/sys/boot/forth/color.4th.8 b/sys/boot/forth/color.4th.8
new file mode 100644
index 0000000..5a734dd
--- /dev/null
+++ b/sys/boot/forth/color.4th.8
@@ -0,0 +1,117 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt COLOR.4TH 8
+.Os
+.Sh NAME
+.Nm color.4th
+.Nd FreeBSD color-detection boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to simplify color logic.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include color.4th
+.Pp
+This line is present in
+.Pa /boot/beastie.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic loader_color?
+Returns TRUE if the
+.Ic loader_color
+environment variable is set to
+.Dq YES
+(case-insensitive) or
+.Dq 1 .
+Otherwise returns FALSE.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_color
+If set to
+.Dq YES
+(case-insensitive) or
+.Dq 1 ,
+causes
+.Ic loader_color?
+to return TRUE, indicating to many other modules that color should be used
+whenever/wherever possible.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/color.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Standard i386
+.Pa /boot/loader.rc :
+.Pp
+Use color where applicable:
+.Pp
+.Bd -literal -offset indent -compact
+loader_color="YES"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr beastie.4th 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/delay.4th b/sys/boot/forth/delay.4th
new file mode 100644
index 0000000..3068e65
--- /dev/null
+++ b/sys/boot/forth/delay.4th
@@ -0,0 +1,112 @@
+\ Copyright (c) 2008-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-delay.4th
+
+2 constant delay_default \ Default delay (in seconds)
+3 constant etx_key \ End-of-Text character produced by Ctrl+C
+13 constant enter_key \ Carriage-Return character produce by ENTER
+27 constant esc_key \ Escape character produced by ESC or Ctrl+[
+
+variable delay_tstart \ state variable used for delay timing
+variable delay_delay \ determined configurable delay duration
+variable delay_cancelled \ state variable for user cancellation
+variable delay_showdots \ whether continually print dots while waiting
+
+: delay_execute ( -- )
+
+ \ make sure that we have a command to execute
+ s" delay_command" getenv dup -1 = if
+ drop exit
+ then
+
+ \ read custom time-duration (if set)
+ s" loader_delay" getenv dup -1 = if
+ drop \ no custom duration (remove dup'd bunk -1)
+ delay_default \ use default setting (replacing bunk -1)
+ else
+ \ make sure custom duration is a number
+ ?number 0= if
+ delay_default \ use default if otherwise
+ then
+ then
+
+ \ initialize state variables
+ delay_delay ! \ stored value is on the stack from above
+ seconds delay_tstart ! \ store the time we started
+ 0 delay_cancelled ! \ boolean flag indicating user-cancelled event
+
+ false delay_showdots ! \ reset to zero and read from environment
+ s" delay_showdots" getenv dup -1 <> if
+ 2drop \ don't need the value, just existance
+ true delay_showdots !
+ else
+ drop
+ then
+
+ \ Loop until we have exceeded the desired time duration
+ begin
+ 25 ms \ sleep for 25 milliseconds (40 iterations/sec)
+
+ \ throw some dots up on the screen if desired
+ delay_showdots @ if
+ ." ." \ dots visually aid in the perception of time
+ then
+
+ \ was a key depressed?
+ key? if
+ key \ obtain ASCII value for keystroke
+ dup enter_key = if
+ -1 delay_delay ! \ break loop
+ then
+ dup etx_key = swap esc_key = OR if
+ -1 delay_delay ! \ break loop
+ -1 delay_cancelled ! \ set cancelled flag
+ then
+ then
+
+ \ if the time duration is set to zero, loop forever
+ \ waiting for either ENTER or Ctrl-C/Escape to be pressed
+ delay_delay @ 0> if
+ \ calculate elapsed time
+ seconds delay_tstart @ - delay_delay @ >
+ else
+ -1 \ break loop
+ then
+ until
+
+ \ if we were throwing up dots, throw up a line-break
+ delay_showdots @ if
+ cr
+ then
+
+ \ did the user press either Ctrl-C or Escape?
+ delay_cancelled @ if
+ 2drop \ we don't need the command string anymore
+ else
+ evaluate \ evaluate/execute the command string
+ then
+;
diff --git a/sys/boot/forth/delay.4th.8 b/sys/boot/forth/delay.4th.8
new file mode 100644
index 0000000..3fe5b5b
--- /dev/null
+++ b/sys/boot/forth/delay.4th.8
@@ -0,0 +1,126 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt DELAY.4TH 8
+.Os
+.Sh NAME
+.Nm delay.4th
+.Nd FreeBSD debugging boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to add debugging capabilities to
+.Xr loader 8 .
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include delay.4th
+.Pp
+This line is present in
+.Pa /boot/beastie.4th
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic delay_execute
+Executes the [string] procedure stored in the
+.Ic delay_command
+environment variable after
+.Ic loader_delay
+seconds.
+.Pp
+If the optional
+.Ic delay_showdots
+environment variable is set, a continuous series of dots is printed.
+.Pp
+During the duration, the user can either press Ctrl-C (or Esc) to abort or
+ENTER to proceed immediately.
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va delay_command
+The command to be executed by
+.Ic delay_execute .
+.It Va loader_delay
+The duration (in seconds) to delay before executing
+.Ic delay_command .
+.It Va delay_showdots
+If set, will cause
+.Ic delay_execute
+to print a continuous series of dots during the delay duration.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/delay.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Introducing a 5-second delay before including another file from
+.Pa /boot/loader.rc :
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/delay.4th
+set delay_command="include /boot/other.4th"
+set delay_showdots
+set loader_delay=5
+delay_execute
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr beastie.4th 8 ,
+.Xr loader.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th
index 7b22b6d..c765147 100644
--- a/sys/boot/forth/loader.4th
+++ b/sys/boot/forth/loader.4th
@@ -89,30 +89,7 @@ builtin: boot-conf
only forth definitions also support-functions
-\ ***** check-password
-\
-\ If a password was defined, execute autoboot and ask for
-\ password if autoboot returns.
-\ Do not exit unless the right password is given.
-
-: check-password
- password .addr @ if
- 0 autoboot
- false >r
- begin
- bell emit bell emit
- ." Password: "
- password .len @ read-password
- dup password .len @ = if
- 2dup password .addr @ password .len @
- compare 0= if r> drop true >r then
- then
- drop free drop
- r@
- until
- r> drop
- then
-;
+include /boot/check-password.4th
\ ***** start
\
diff --git a/sys/boot/forth/loader.conf.5 b/sys/boot/forth/loader.conf.5
index 6abb7ea..c8c61c6 100644
--- a/sys/boot/forth/loader.conf.5
+++ b/sys/boot/forth/loader.conf.5
@@ -215,14 +215,20 @@ be displayed.
If set to
.Dq YES ,
the beastie boot menu will be skipped.
-.It Va loader_logo Pq Dq Li fbsdbw
+.It Va loader_logo Pq Dq Li orbbw
Selects a desired logo in the beastie boot menu.
Possible values are:
+.Dq Li orbbw ,
+.Dq Li orb ,
.Dq Li fbsdbw ,
.Dq Li beastiebw ,
.Dq Li beastie ,
and
.Dq Li none .
+.It Va loader_color
+If set to
+.Dq YES ,
+the beastie boot menu will be displayed using ANSI coloring where possible.
.El
.Sh FILES
.Bl -tag -width /boot/defaults/loader.conf -compact
diff --git a/sys/boot/forth/loader.rc b/sys/boot/forth/loader.rc
index 0f9d37e..6443f3f 100644
--- a/sys/boot/forth/loader.rc
+++ b/sys/boot/forth/loader.rc
@@ -10,5 +10,8 @@ start
\ Tests for password -- executes autoboot first if a password was defined
check-password
-\ Unless set otherwise, autoboot is automatic at this point
+\ Load in the boot menu
+include /boot/beastie.4th
+\ Start the boot menu
+beastie-start
diff --git a/sys/boot/forth/menu-commands.4th b/sys/boot/forth/menu-commands.4th
new file mode 100644
index 0000000..828a148
--- /dev/null
+++ b/sys/boot/forth/menu-commands.4th
@@ -0,0 +1,190 @@
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-menu-commands.4th
+
+: acpi_enable ( -- )
+ s" set acpi_load=YES" evaluate \ XXX deprecated but harmless
+ s" set hint.acpi.0.disabled=0" evaluate
+ s" loader.acpi_disabled_by_user" unsetenv
+;
+
+: acpi_disable ( -- )
+ s" acpi_load" unsetenv \ XXX deprecated but harmless
+ s" set hint.acpi.0.disabled=1" evaluate
+ s" set loader.acpi_disabled_by_user=1" evaluate
+;
+
+: toggle_acpi ( N -- N TRUE )
+
+ \ Make changes effective _before_ calling menu-redraw
+
+ acpienabled? if
+ acpi_disable
+ else
+ acpi_enable
+ then
+
+ menu-redraw
+
+ TRUE \ loop menu again
+;
+
+: toggle_safemode ( N -- N TRUE )
+ toggle_menuitem
+
+ \ Now we're going to make the change effective
+
+ s" toggle_stateN @" \ base name of toggle state var
+ -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
+
+ evaluate 0= if
+ s" hint.apic.0.disabled" unsetenv
+ s" hw.ata.ata_dma" unsetenv
+ s" hw.ata.atapi_dma" unsetenv
+ s" hw.ata.wc" unsetenv
+ s" hw.eisa_slots" unsetenv
+ s" hint.kbdmux.0.disabled" unsetenv
+ else
+ \
+ \ Toggle ACPI elements if necessary
+ \
+ acpipresent? if acpienabled? if
+ menuacpi @ dup 0<> if
+ toggle_menuitem ( N -- N )
+ then
+ drop
+ acpi_disable
+ then then
+
+ s" set hint.apic.0.disabled=1" evaluate
+ s" set hw.ata.ata_dma=0" evaluate
+ s" set hw.ata.atapi_dma=0" evaluate
+ s" set hw.ata.wc=0" evaluate
+ s" set hw.eisa_slots=0" evaluate
+ s" set hint.kbdmux.0.disabled=1" evaluate
+ then
+
+ menu-redraw
+
+ TRUE \ loop menu again
+;
+
+: toggle_singleuser ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ s" toggle_stateN @" \ base name of toggle state var
+ -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
+
+ evaluate 0= if
+ s" boot_single" unsetenv
+ else
+ s" set boot_single=YES" evaluate
+ then
+
+ TRUE \ loop menu again
+;
+
+: toggle_verbose ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ s" toggle_stateN @" \ base name of toggle state var
+ -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
+
+ evaluate 0= if
+ s" boot_verbose" unsetenv
+ else
+ s" set boot_verbose=YES" evaluate
+ then
+
+ TRUE \ loop menu again
+;
+
+: goto_prompt ( N -- N FALSE )
+
+ s" set autoboot_delay=NO" evaluate
+
+ cr
+ ." To get back to the menu, type `menu' and press ENTER" cr
+ ." or type `boot' and press ENTER to start FreeBSD." cr
+ cr
+
+ FALSE \ exit the menu
+;
+
+: cycle_kernel ( N -- N TRUE )
+ cycle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ s" cycle_stateN" \ base name of array state var
+ -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral
+ evaluate \ translate name into address
+ @ \ dereference address into value
+ 48 + \ convert to ASCII numeral
+
+ \ Since we are [in this file] going to override the standard `boot'
+ \ routine with a custom one, you should know that we use $kernel
+ \ when referencing the desired kernel. Set $kernel below.
+
+ s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
+ \ command to assemble full kernel-path
+ -rot tuck 36 + c! swap \ replace 'N' with array index value
+ evaluate \ sets $kernel to full kernel-path
+
+ TRUE \ loop menu again
+;
+
+: cycle_root ( N -- N TRUE )
+ cycle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ s" cycle_stateN" \ base name of array state var
+ -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral
+ evaluate \ translate name into address
+ @ \ dereference address into value
+ 48 + \ convert to ASCII numeral
+
+ \ Since we are [in this file] going to override the standard `boot'
+ \ routine with a custom one, you should know that we use $root when
+ \ booting. Set $root below.
+
+ s" set root=${root_prefix}${root[N]}${root_prefix}"
+ \ command to assemble full kernel-path
+ -rot tuck 30 + c! swap \ replace 'N' with array index value
+ evaluate \ sets $kernel to full kernel-path
+
+ TRUE \ loop menu again
+;
diff --git a/sys/boot/forth/menu.4th b/sys/boot/forth/menu.4th
new file mode 100644
index 0000000..110ec1c
--- /dev/null
+++ b/sys/boot/forth/menu.4th
@@ -0,0 +1,971 @@
+\ Copyright (c) 2003 Scott Long <scottl@freebsd.org>
+\ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-menu.4th
+
+\ Frame drawing
+include /boot/frames.4th
+
+f_double \ Set frames to double (see frames.4th). Replace with
+ \ f_single if you want single frames.
+46 constant dot \ ASCII definition of a period (in decimal)
+
+ 4 constant menu_timeout_default_x \ default column position of timeout
+23 constant menu_timeout_default_y \ default row position of timeout msg
+10 constant menu_timeout_default \ default timeout (in seconds)
+
+\ Customize the following values with care
+
+ 1 constant menu_start \ Numerical prefix of first menu item
+dot constant bullet \ Menu bullet (appears after numerical prefix)
+ 5 constant menu_x \ Row position of the menu (from the top)
+ 10 constant menu_y \ Column position of the menu (from left side)
+
+\ Menu Appearance
+variable menuidx \ Menu item stack for number prefixes
+variable menurow \ Menu item stack for positioning
+variable menubllt \ Menu item bullet
+
+\ Menu Positioning
+variable menuX \ Menu X offset (columns)
+variable menuY \ Menu Y offset (rows)
+
+\ Menu-item key association/detection
+variable menukey1
+variable menukey2
+variable menukey3
+variable menukey4
+variable menukey5
+variable menukey6
+variable menukey7
+variable menukey8
+variable menureboot
+variable menurebootadded
+variable menuacpi
+variable menuoptions
+
+\ Menu timer [count-down] variables
+variable menu_timeout_enabled \ timeout state (internal use only)
+variable menu_time \ variable for tracking the passage of time
+variable menu_timeout \ determined configurable delay duration
+variable menu_timeout_x \ column position of timeout message
+variable menu_timeout_y \ row position of timeout message
+
+\ Boolean option status variables
+variable toggle_state1
+variable toggle_state2
+variable toggle_state3
+variable toggle_state4
+variable toggle_state5
+variable toggle_state6
+variable toggle_state7
+variable toggle_state8
+
+\ Array option status variables
+variable cycle_state1
+variable cycle_state2
+variable cycle_state3
+variable cycle_state4
+variable cycle_state5
+variable cycle_state6
+variable cycle_state7
+variable cycle_state8
+
+\ Containers for storing the initial caption text
+create init_text1 255 allot
+create init_text2 255 allot
+create init_text3 255 allot
+create init_text4 255 allot
+create init_text5 255 allot
+create init_text6 255 allot
+create init_text7 255 allot
+create init_text8 255 allot
+
+: arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise.
+ s" arch-i386" environment? dup if
+ drop
+ then
+;
+
+\ This function prints a menu item at menuX (row) and menuY (column), returns
+\ the incremental decimal ASCII value associated with the menu item, and
+\ increments the cursor position to the next row for the creation of the next
+\ menu item. This function is called by the menu-create function. You need not
+\ call it directly.
+\
+: printmenuitem ( menu_item_str -- ascii_keycode )
+
+ menurow dup @ 1+ swap ! ( increment menurow )
+ menuidx dup @ 1+ swap ! ( increment menuidx )
+
+ \ Calculate the menuitem row position
+ menurow @ menuY @ +
+
+ \ Position the cursor at the menuitem position
+ dup menuX @ swap at-xy
+
+ \ Print the value of menuidx
+ loader_color? if
+ ." "
+ then
+ menuidx @ .
+ loader_color? if
+ ." "
+ then
+
+ \ Move the cursor forward 1 column
+ dup menuX @ 1+ swap at-xy
+
+ menubllt @ emit \ Print the menu bullet using the emit function
+
+ \ Move the cursor to the 3rd column from the current position
+ \ to allow for a space between the numerical prefix and the
+ \ text caption
+ menuX @ 3 + swap at-xy
+
+ \ Print the menu caption (we expect a string to be on the stack
+ \ prior to invoking this function)
+ type
+
+ \ Here we will add the ASCII decimal of the numerical prefix
+ \ to the stack (decimal ASCII for `1' is 49) as a "return value"
+ menuidx @ 48 +
+;
+
+: toggle_menuitem ( N -- N ) \ toggles caption text and internal menuitem state
+
+ \ ASCII numeral equal to user-selected menu item must be on the stack.
+ \ We do not modify the stack, so the ASCII numeral is left on top.
+
+ s" init_textN" \ base name of buffer
+ -rot 2dup 9 + c! rot \ replace 'N' with ASCII num
+
+ evaluate c@ 0= if
+ \ NOTE: no need to check toggle_stateN since the first time we
+ \ are called, we will populate init_textN. Further, we don't
+ \ need to test whether menu_caption[x] (ansi_caption[x] when
+ \ loader_color=1) is available since we would not have been
+ \ called if the caption was NULL.
+
+ \ base name of environment variable
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ -rot 2dup 13 + c! rot \ replace 'x' with ASCII numeral
+
+ getenv dup -1 <> if
+
+ s" init_textN" \ base name of buffer
+ 4 pick \ copy ASCII num to top
+ rot tuck 9 + c! swap \ replace 'N' with ASCII num
+ evaluate
+
+ \ now we have the buffer c-addr on top
+ \ ( followed by c-addr/u of current caption )
+
+ \ Copy the current caption into our buffer
+ 2dup c! -rot \ store strlen at first byte
+ begin
+ rot 1+ \ bring alt addr to top and increment
+ -rot -rot \ bring buffer addr to top
+ 2dup c@ swap c! \ copy current character
+ 1+ \ increment buffer addr
+ rot 1- \ bring buffer len to top and decrement
+ dup 0= \ exit loop if buffer len is zero
+ until
+ 2drop \ buffer len/addr
+ drop \ alt addr
+
+ else
+ drop
+ then
+ then
+
+ \ Now we are certain to have init_textN populated with the initial
+ \ value of menu_caption[x] (ansi_caption[x] with loader_color enabled).
+ \ We can now use init_textN as the untoggled caption and
+ \ toggled_text[x] (toggled_ansi[x] with loader_color enabled) as the
+ \ toggled caption and store the appropriate value into menu_caption[x]
+ \ (again, ansi_caption[x] with loader_color enabled). Last, we'll
+ \ negate the toggled state so that we reverse the flow on subsequent
+ \ calls.
+
+ s" toggle_stateN @" \ base name of toggle state var
+ -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
+
+ evaluate 0= if
+ \ state is OFF, toggle to ON
+
+ \ base name of toggled text var
+ loader_color? if
+ s" toggled_ansi[x]"
+ else
+ s" toggled_text[x]"
+ then
+ -rot 2dup 13 + c! rot \ replace 'x' with ASCII num
+
+ getenv dup -1 <> if
+ \ Assign toggled text to menu caption
+
+ \ base name of caption var
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ 4 pick \ copy ASCII num to top
+ rot tuck 13 + c! swap \ replace 'x' with ASCII num
+
+ setenv \ set new caption
+ else
+ \ No toggled text, keep the same caption
+
+ drop
+ then
+
+ true \ new value of toggle state var (to be stored later)
+ else
+ \ state is ON, toggle to OFF
+
+ s" init_textN" \ base name of initial text buffer
+ -rot 2dup 9 + c! rot \ replace 'N' with ASCII numeral
+ evaluate \ convert string to c-addr
+ count \ convert c-addr to c-addr/u
+
+ \ base name of caption var
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ 4 pick \ copy ASCII num to top
+ rot tuck 13 + c! swap \ replace 'x' with ASCII numeral
+
+ setenv \ set new caption
+ false \ new value of toggle state var (to be stored below)
+ then
+
+ \ now we'll store the new toggle state (on top of stack)
+ s" toggle_stateN" \ base name of toggle state var
+ 3 pick \ copy ASCII numeral to top
+ rot tuck 12 + c! swap \ replace 'N' with ASCII numeral
+ evaluate \ convert string to addr
+ ! \ store new value
+;
+
+: cycle_menuitem ( N -- N ) \ cycles through array of choices for a menuitem
+
+ \ ASCII numeral equal to user-selected menu item must be on the stack.
+ \ We do not modify the stack, so the ASCII numeral is left on top.
+
+ s" cycle_stateN" \ base name of array state var
+ -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral
+
+ evaluate \ we now have a pointer to the proper variable
+ dup @ \ resolve the pointer (but leave it on the stack)
+ 1+ \ increment the value
+
+ \ Before assigning the (incremented) value back to the pointer,
+ \ let's test for the existence of this particular array element.
+ \ If the element exists, we'll store index value and move on.
+ \ Otherwise, we'll loop around to zero and store that.
+
+ dup 48 + \ duplicate Array index and convert to ASCII numeral
+
+ \ base name of array caption text
+ loader_color? if
+ s" ansi_caption[x][y]"
+ else
+ s" menu_caption[x][y]"
+ then
+ -rot tuck 16 + c! swap \ replace 'y' with Array index
+ 4 pick rot tuck 13 + c! swap \ replace 'x' with menu choice
+
+ \ Now test for the existence of our incremented array index in the
+ \ form of $menu_caption[x][y] ($ansi_caption[x][y] with loader_color
+ \ enabled) as set in loader.rc(5), et. al.
+
+ getenv dup -1 = if
+ \ No caption set for this array index. Loop back to zero.
+
+ drop ( getenv cruft )
+ drop ( incremented array index )
+ 0 ( new array index that will be stored later )
+
+ \ base name of caption var
+ loader_color? if
+ s" ansi_caption[x][0]"
+ else
+ s" menu_caption[x][0]"
+ then
+ 4 pick rot tuck 13 + c! swap \ replace 'x' with menu choice
+
+ getenv dup -1 = if
+ \ This is highly unlikely to occur, but to make
+ \ sure that things move along smoothly, allocate
+ \ a temporary NULL string
+
+ s" "
+ then
+ then
+
+ \ At this point, we should have the following on the stack (in order,
+ \ from bottom to top):
+ \
+ \ N - Ascii numeral representing the menu choice (inherited)
+ \ Addr - address of our internal cycle_stateN variable
+ \ N - zero-based number we intend to store to the above
+ \ C-Addr - string value we intend to store to menu_caption[x]
+ \ (or ansi_caption[x] with loader_color enabled)
+ \
+ \ Let's perform what we need to with the above.
+
+ \ base name of menuitem caption var
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ 6 pick rot tuck 13 + c! swap \ replace 'x' with menu choice
+ setenv \ set the new caption
+
+ swap ! \ update array state variable
+;
+
+: acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise
+ s" hint.acpi.0.rsdp" getenv
+ dup -1 = if
+ drop false exit
+ then
+ 2drop
+ true
+;
+
+: acpienabled? ( -- flag ) \ Returns TRUE if ACPI is enabled, FALSE otherwise
+ s" hint.acpi.0.disabled" getenv
+ dup -1 <> if
+ s" 0" compare 0<> if
+ false exit
+ then
+ else
+ drop
+ then
+ true
+;
+
+\ This function prints the appropriate menuitem basename to the stack if an
+\ ACPI option is to be presented to the user, otherwise returns -1. Used
+\ internally by menu-create, you need not (nor should you) call this directly.
+\
+: acpimenuitem ( -- C-Addr | -1 )
+
+ arch-i386? if
+ acpipresent? if
+ acpienabled? if
+ loader_color? if
+ s" toggled_ansi[x]"
+ else
+ s" toggled_text[x]"
+ then
+ else
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ then
+ else
+ menuidx dup @ 1+ swap ! ( increment menuidx )
+ -1
+ then
+ else
+ -1
+ then
+;
+
+\ This function creates the list of menu items. This function is called by the
+\ menu-display function. You need not be call it directly.
+\
+: menu-create ( -- )
+
+ \ Print the frame caption at (x,y)
+ s" loader_menu_title" getenv dup -1 = if
+ drop s" Welcome to FreeBSD"
+ then
+ 24 over 2 / - 9 at-xy type
+
+ \ Print our menu options with respective key/variable associations.
+ \ `printmenuitem' ends by adding the decimal ASCII value for the
+ \ numerical prefix to the stack. We store the value left on the stack
+ \ to the key binding variable for later testing against a character
+ \ captured by the `getkey' function.
+
+ \ Note that any menu item beyond 9 will have a numerical prefix on the
+ \ screen consisting of the first digit (ie. 1 for the tenth menu item)
+ \ and the key required to activate that menu item will be the decimal
+ \ ASCII of 48 plus the menu item (ie. 58 for the tenth item, aka. `:')
+ \ which is misleading and not desirable.
+ \
+ \ Thus, we do not allow more than 8 configurable items on the menu
+ \ (with "Reboot" as the optional ninth and highest numbered item).
+
+ \
+ \ Initialize the ACPI option status.
+ \
+ 0 menuacpi !
+ s" menu_acpi" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ menuacpi !
+ arch-i386? if acpipresent? if
+ \
+ \ Set menu toggle state to active state
+ \ (required by generic toggle_menuitem)
+ \
+ menuacpi @
+ s" acpienabled? toggle_stateN !"
+ -rot tuck 25 + c! swap
+ evaluate
+ then then
+ else
+ drop
+ then
+ then
+
+ \
+ \ Initialize the menu_options visual separator.
+ \
+ 0 menuoptions !
+ s" menu_options" getenv -1 <> if
+ c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+ menuoptions !
+ else
+ drop
+ then
+ then
+
+ \ Initialize "Reboot" menu state variable (prevents double-entry)
+ false menurebootadded !
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ \ If the "Options:" separator, print it.
+ dup menuoptions @ = if
+ \ Optionally add a reboot option to the menu
+ s" menu_reboot" getenv -1 <> if
+ drop
+ s" Reboot" printmenuitem menureboot !
+ true menurebootadded !
+ then
+
+ menuX @
+ menurow @ 2 + menurow !
+ menurow @ menuY @ +
+ at-xy
+ ." Options:"
+ then
+
+ \ If this is the ACPI menu option, act accordingly.
+ dup menuacpi @ = if
+ acpimenuitem ( -- C-Addr | -1 )
+ else
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ then
+
+ ( C-Addr | -1 )
+ dup -1 <> if
+ \ replace 'x' with current iteration
+ -rot 2dup 13 + c! rot
+
+ \ test for environment variable
+ getenv dup -1 <> if
+ printmenuitem ( C-Addr -- N )
+
+ s" menukeyN !" \ generate cmd to store result
+ -rot 2dup 7 + c! rot
+
+ evaluate
+ else
+ drop
+ then
+ else
+ drop
+
+ s" menu_command[x]"
+ -rot 2dup 13 + c! rot ( replace 'x' )
+ unsetenv
+ then
+
+ 1+ dup 56 > \ add 1 to iterator, continue if less than 57
+ until
+ drop \ iterator
+
+ \ Optionally add a reboot option to the menu
+ menurebootadded @ true <> if
+ s" menu_reboot" getenv -1 <> if
+ drop \ no need for the value
+ s" Reboot" \ menu caption (required by printmenuitem)
+
+ printmenuitem
+ menureboot !
+ else
+ 0 menureboot !
+ then
+ then
+;
+
+\ Takes a single integer on the stack and updates the timeout display. The
+\ integer must be between 0 and 9 (we will only update a single digit in the
+\ source message).
+\
+: menu-timeout-update ( N -- )
+
+ dup 9 > if ( N N 9 -- N )
+ drop ( N -- )
+ 9 ( maximum: -- N )
+ then
+
+ dup 0 < if ( N N 0 -- N )
+ drop ( N -- )
+ 0 ( minimum: -- N )
+ then
+
+ 48 + ( convert single-digit numeral to ASCII: N 48 -- N )
+
+ s" Autoboot in N seconds. [Space] to pause" ( N -- N Addr C )
+
+ 2 pick 48 - 0> if ( N Addr C N 48 -- N Addr C )
+
+ \ Modify 'N' (Addr+12) above to reflect time-left
+
+ -rot ( N Addr C -- C N Addr )
+ tuck ( C N Addr -- C Addr N Addr )
+ 12 + ( C Addr N Addr -- C Addr N Addr2 )
+ c! ( C Addr N Addr2 -- C Addr )
+ swap ( C Addr -- Addr C )
+
+ menu_timeout_x @
+ menu_timeout_y @
+ at-xy ( position cursor: Addr C N N -- Addr C )
+
+ type ( print message: Addr C -- )
+
+ else ( N Addr C N -- N Addr C )
+
+ menu_timeout_x @
+ menu_timeout_y @
+ at-xy ( position cursor: N Addr C N N -- N Addr C )
+
+ spaces ( erase message: N Addr C -- N Addr )
+ 2drop ( N Addr -- )
+
+ then
+
+ 0 25 at-xy ( position cursor back at bottom-left )
+;
+
+\ This function blocks program flow (loops forever) until a key is pressed.
+\ The key that was pressed is added to the top of the stack in the form of its
+\ decimal ASCII representation. This function is called by the menu-display
+\ function. You need not call it directly.
+\
+: getkey ( -- ascii_keycode )
+
+ begin \ loop forever
+
+ menu_timeout_enabled @ 1 = if
+ ( -- )
+ seconds ( get current time: -- N )
+ dup menu_time @ <> if ( has time elapsed?: N N N -- N )
+
+ \ At least 1 second has elapsed since last loop
+ \ so we will decrement our "timeout" (really a
+ \ counter, insuring that we do not proceed too
+ \ fast) and update our timeout display.
+
+ menu_time ! ( update time record: N -- )
+ menu_timeout @ ( "time" remaining: -- N )
+ dup 0> if ( greater than 0?: N N 0 -- N )
+ 1- ( decrement counter: N -- N )
+ dup menu_timeout !
+ ( re-assign: N N Addr -- N )
+ then
+ ( -- N )
+
+ dup 0= swap 0< or if ( N <= 0?: N N -- )
+ \ halt the timer
+ 0 menu_timeout ! ( 0 Addr -- )
+ 0 menu_timeout_enabled ! ( 0 Addr -- )
+ then
+
+ \ update the timer display ( N -- )
+ menu_timeout @ menu-timeout-update
+
+ menu_timeout @ 0= if
+ \ We've reached the end of the timeout
+ \ (user did not cancel by pressing ANY
+ \ key)
+
+ s" menu_timeout_command" getenv dup
+ -1 = if
+ drop \ clean-up
+ else
+ evaluate
+ then
+ then
+
+ else ( -- N )
+ \ No [detectable] time has elapsed (in seconds)
+ drop ( N -- )
+ then
+ ( -- )
+ then
+
+ key? if \ Was a key pressed? (see loader(8))
+
+ \ An actual key was pressed (if the timeout is running,
+ \ kill it regardless of which key was pressed)
+ menu_timeout @ 0<> if
+ 0 menu_timeout !
+ 0 menu_timeout_enabled !
+
+ \ clear screen of timeout message
+ 0 menu-timeout-update
+ then
+
+ \ get the key that was pressed and exit (if we
+ \ get a non-zero ASCII code)
+ key dup 0<> if
+ exit
+ else
+ drop
+ then
+ then
+ 50 ms \ sleep for 50 milliseconds (see loader(8))
+
+ again
+;
+
+: menu-erase ( -- ) \ Erases menu and resets positioning variable to positon 1.
+
+ \ Clear the screen area associated with the interactive menu
+ menuX @ menuY @
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces
+ 2drop
+
+ \ Reset the starting index and position for the menu
+ menu_start 1- menuidx !
+ 0 menurow !
+;
+
+\ Erase and redraw the menu. Useful if you change a caption and want to
+\ update the menu to reflect the new value.
+\
+: menu-redraw ( -- )
+ menu-erase
+ menu-create
+;
+
+\ This function initializes the menu. Call this from your `loader.rc' file
+\ before calling any other menu-related functions.
+\
+: menu-init ( -- )
+ menu_start
+ 1- menuidx ! \ Initialize the starting index for the menu
+ 0 menurow ! \ Initialize the starting position for the menu
+ 42 13 2 9 box \ Draw frame (w,h,x,y)
+ 0 25 at-xy \ Move cursor to the bottom for output
+;
+
+\ Main function. Call this from your `loader.rc' file.
+\
+: menu-display ( -- )
+
+ 0 menu_timeout_enabled ! \ start with automatic timeout disabled
+
+ \ check indication that automatic execution after delay is requested
+ s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr )
+ drop ( just testing existence right now: Addr -- )
+
+ \ initialize state variables
+ seconds menu_time ! ( store the time we started )
+ 1 menu_timeout_enabled ! ( enable automatic timeout )
+
+ \ read custom time-duration (if set)
+ s" autoboot_delay" getenv dup -1 = if
+ drop \ no custom duration (remove dup'd bunk -1)
+ menu_timeout_default \ use default setting
+ else
+ 2dup ?number 0= if ( if not a number )
+ \ disable timeout if "NO", else use default
+ s" NO" compare-insensitive 0= if
+ 0 menu_timeout_enabled !
+ 0 ( assigned to menu_timeout below )
+ else
+ menu_timeout_default
+ then
+ else
+ -rot 2drop
+
+ \ disable timeout if less than zero
+ dup 0< if
+ drop
+ 0 menu_timeout_enabled !
+ 0 ( assigned to menu_timeout below )
+ then
+ then
+ then
+ menu_timeout ! ( store value on stack from above )
+
+ menu_timeout_enabled @ 1 = if
+ \ read custom column position (if set)
+ s" loader_menu_timeout_x" getenv dup -1 = if
+ drop \ no custom column position
+ menu_timeout_default_x \ use default setting
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_timeout_default_x \ or use default
+ then
+ then
+ menu_timeout_x ! ( store value on stack from above )
+
+ \ read custom row position (if set)
+ s" loader_menu_timeout_y" getenv dup -1 = if
+ drop \ no custom row position
+ menu_timeout_default_y \ use default setting
+ else
+ \ make sure custom position is a number
+ ?number 0= if
+ menu_timeout_default_y \ or use default
+ then
+ then
+ menu_timeout_y ! ( store value on stack from above )
+ then
+ then
+
+ menu-create
+
+ begin \ Loop forever
+
+ 0 25 at-xy \ Move cursor to the bottom for output
+ getkey \ Block here, waiting for a key to be pressed
+
+ dup -1 = if
+ drop exit \ Caught abort (abnormal return)
+ then
+
+ \ Boot if the user pressed Enter/Ctrl-M (13) or
+ \ Ctrl-Enter/Ctrl-J (10)
+ dup over 13 = swap 10 = or if
+ drop ( no longer needed )
+ s" boot" evaluate
+ exit ( pedantic; never reached )
+ then
+
+ \ Evaluate the decimal ASCII value against known menu item
+ \ key associations and act accordingly
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ s" menukeyN @"
+
+ \ replace 'N' with current iteration
+ -rot 2dup 7 + c! rot
+
+ evaluate rot tuck = if
+
+ \ Adjust for missing ACPI menuitem on non-i386
+ arch-i386? true <> menuacpi @ 0<> and if
+ menuacpi @ over 2dup < -rot = or
+ over 58 < and if
+ ( key >= menuacpi && key < 58: N -- N )
+ 1+
+ then
+ then
+
+ \ base env name for the value (x is a number)
+ s" menu_command[x]"
+
+ \ Copy ASCII number to string at offset 13
+ -rot 2dup 13 + c! rot
+
+ \ Test for the environment variable
+ getenv dup -1 <> if
+ \ Execute the stored procedure
+ evaluate
+
+ \ We expect there to be a non-zero
+ \ value left on the stack after
+ \ executing the stored procedure.
+ \ If so, continue to run, else exit.
+
+ 0= if
+ drop \ key pressed
+ drop \ loop iterator
+ exit
+ else
+ swap \ need iterator on top
+ then
+ then
+
+ \ Re-adjust for missing ACPI menuitem
+ arch-i386? true <> menuacpi @ 0<> and if
+ swap
+ menuacpi @ 1+ over 2dup < -rot = or
+ over 59 < and if
+ 1-
+ then
+ swap
+ then
+ else
+ swap \ need iterator on top
+ then
+
+ \
+ \ Check for menu keycode shortcut(s)
+ \
+ s" menu_keycode[x]"
+ -rot 2dup 13 + c! rot
+ getenv dup -1 = if
+ drop
+ else
+ ?number 0<> if
+ rot tuck = if
+ swap
+ s" menu_command[x]"
+ -rot 2dup 13 + c! rot
+ getenv dup -1 <> if
+ evaluate
+ 0= if
+ 2drop
+ exit
+ then
+ else
+ drop
+ then
+ else
+ swap
+ then
+ then
+ then
+
+ 1+ dup 56 > \ increment iterator
+ \ continue if less than 57
+ until
+ drop \ loop iterator
+
+ menureboot @ = if 0 reboot then
+
+ again \ Non-operational key was pressed; repeat
+;
+
+\ This function unsets all the possible environment variables associated with
+\ creating the interactive menu. Call this when you want to clear the menu
+\ area in preparation for another menu.
+\
+: menu-clear ( -- )
+
+ 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
+ begin
+ \ basename for caption variable
+ loader_color? if
+ s" ansi_caption[x]"
+ else
+ s" menu_caption[x]"
+ then
+ -rot 2dup 13 + c! rot \ replace 'x' with current iteration
+ unsetenv \ not erroneous to unset unknown var
+
+ s" 0 menukeyN !" \ basename for key association var
+ -rot 2dup 9 + c! rot \ replace 'N' with current iteration
+ evaluate \ assign zero (0) to key assoc. var
+
+ 1+ dup 56 > \ increment, continue if less than 57
+ until
+ drop \ iterator
+
+ \ clear the "Reboot" menu option flag
+ s" menu_reboot" unsetenv
+ 0 menureboot !
+
+ \ clear the ACPI menu option flag
+ s" menu_acpi" unsetenv
+ 0 menuacpi !
+
+ \ clear the "Options" menu separator flag
+ s" menu_options" unsetenv
+ 0 menuoptions !
+
+ menu-erase
+;
+
+\ Assign configuration values
+bullet menubllt !
+10 menuY !
+5 menuX !
+
+\ Initialize our boolean state variables
+0 toggle_state1 !
+0 toggle_state2 !
+0 toggle_state3 !
+0 toggle_state4 !
+0 toggle_state5 !
+0 toggle_state6 !
+0 toggle_state7 !
+0 toggle_state8 !
+
+\ Initialize our array state variables
+0 cycle_state1 !
+0 cycle_state2 !
+0 cycle_state3 !
+0 cycle_state4 !
+0 cycle_state5 !
+0 cycle_state6 !
+0 cycle_state7 !
+0 cycle_state8 !
+
+\ Initialize string containers
+0 init_text1 c!
+0 init_text2 c!
+0 init_text3 c!
+0 init_text4 c!
+0 init_text5 c!
+0 init_text6 c!
+0 init_text7 c!
+0 init_text8 c!
diff --git a/sys/boot/forth/menu.4th.8 b/sys/boot/forth/menu.4th.8
new file mode 100644
index 0000000..45388f5
--- /dev/null
+++ b/sys/boot/forth/menu.4th.8
@@ -0,0 +1,307 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2011
+.Dt MENU.4TH 8
+.Os
+.Sh NAME
+.Nm menu.4th
+.Nd FreeBSD dynamic menu boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to display a dynamic menu system managed through
+a system of carefully named environment variables.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include menu.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic menu-init
+Draws the menu bounding box and initializes some internal state variables.
+This should be called before any other menu-related functions.
+.It Ic menu-display
+Displays the menu (configured via the below documented environment variables)
+and blocks on keyboard input, awaiting user action.
+.It Ic menu-erase
+Clears the screen area within the menu bounding box.
+.It Ic menu-redraw
+Calls
+.Ic menu-erase
+and then redraws the menu.
+.It Ic menu-clear
+Unsets all possible environment variables used
+to configure the menu and then calls
+.Ic menu-erase .
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_color
+If set to
+.Dq Li YES
+(case-insensitive) or
+.Dq Li 1 ,
+causes the menu to be displayed in color wherever possible. This includes the
+use of ANSI bold for numbers appearing to the left of menuitems and the use of
+special
+.Dq Li ansi
+variables describd below.
+.It Va autoboot_delay
+Number of seconds
+.Ic menu-display
+will wait before executing
+.Va menu_timeout_command
+.Ic ( boot
+by default) unless a key is pressed.
+If set to
+.Dq Li NO
+(case-insensitive) or
+.Dq Li -1 ,
+.Ic menu-display
+will wait for user input and never execute
+.Ic menu_timeout_command .
+Default is
+.Dq Li 10 .
+See
+.Xr loader 8
+for additional information.
+.It Va menu_timeout_command
+The command to be executed after
+.Va autoboot_delay
+seconds if a key is not pressed. The default is
+.Ic boot .
+.It Va loader_menu_timeout_x
+Sets the desired column position of the timeout countdown text. Default is 4.
+.It Va loader_menu_timeout_y
+Sets the desired row position of the timeout countdown text. Default is 23.
+.It Va loader_menu_title
+The text to display centered above the menu. Default is
+.Dq Li "Welcome to FreeBSD" .
+.It Va menu_caption[x]
+The text to be displayed for the numbered menuitem
+.Dq Li x .
+.It Va menu_command[x]
+The command to be executed when the number associated with menuitem
+.Dq Li x
+is pressed. See the list of included FICL words below for some ideas.
+.It Va menu_keycode[x]
+An optional decimal ASCII keycode to be associated with menuitem
+.Dq Li x .
+When pressed, will cause the execution of
+.Va menu_command[x] .
+.It Va ansi_caption[x]
+If
+.Va loader_color
+is set, use this caption for menuitem
+.Dq Li x
+instead of
+.Va menu_caption[x] .
+.It Va toggled_text[x]
+For menuitems where
+.Va menu_command[x]
+is set to
+.Dq Li toggle_menuitem
+(or a derivative thereof), the text displayed
+will toggle between this and
+.Va menu_caption[x] .
+.It Va toggled_ansi[x]
+Like
+.Va toggled_text[x]
+except used when
+.Va loader_color
+is enabled.
+.It Va menu_caption[x][y]
+For menuitems where
+.Va menu_command[x]
+is set to
+.Dq Li cycle_menuitem
+(or a derivative thereof), the text displayed will cycle between this and other
+.Va menu_caption[x][y]
+entries.
+.It Va ansi_caption[x][y]
+Like
+.Va menu_caption[x][y]
+except used when
+.Va loader_color
+is enabled.
+.It Va menu_acpi
+When set to a number
+.Dq Li x
+associated with a given menuitem, that menuitem will only appear when
+running on i386-compatible hardware,
+.Va hint.acpi.0.rsdp
+is set (indicating the presence of hardware ACPI support as detected by
+.Xr loader 8 ) ,
+and
+.Va hint.acpi.0.disabled
+is not set.
+On non-i386 hardware, menuitems configured after the
+.Dq Li menu_acpi
+menuitem will use a lower number (to compensate for the missing ACPI menuitem)
+but continue to function as expected.
+On i386-compatible hardware lacking ACPI support (as detected by
+.Xr loader 8 ) ,
+subsequent menuitems will retain their associated numbers.
+.It Va hint.acpi.0.rsdp
+Set automatically by
+.Xr loader 8
+on i386-compatible hardware when ACPI support is detected at boot time.
+Effects the display of the
+.Dq Li menu_acpi
+menuitem (if configured).
+.It Va hint.acpi.0.disabled
+Effects the display of the
+.Va menu_acpi
+menuitem. If set, the menuitem will display
+.Va toggled_text[x]
+.Va ( toggled_ansi[x]
+if
+.Va loader_color
+is set), otherwise
+.Va menu_caption[x]
+.Va ( ansi_caption[x]
+if
+.Va loader_color
+is set).
+.It Va menu_options
+When set to a number
+.Dq Li x ,
+a single blank-line and an
+.Dq Li Options
+header are inserted between
+.Va menu_caption[x-1]
+and
+.Va menu_caption[x]
+(if configured).
+.It Va menu_reboot
+If set, adds a built-in
+.Dq Li Reboot
+menuitem to the end of the last configured menuitem. If
+.Va menu_options
+is configured, the
+.Dq Li Reboot
+menuitem will be inserted before the
+.Dq Options
+separator.
+.El
+.Pp
+In addition, it provides the following FICL words:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic arch-i386? ( -- BOOL )
+Returns true (-1) on i386 and false (0) otherwise.
+.It Ic acpipresent? ( -- BOOL )
+Returns true (-1) if ACPI is present and false (0) otherwise.
+.It Ic acpienabled? ( -- BOOL )
+Returns true (-1) if ACPI is enabled and false (0) otherwise.
+.It Ic toggle_menuitem ( N -- N )
+Toggles menuitem
+.Dq Li N
+between
+.Va menu_caption[x]
+and
+.Va toggled_text[x]
+(where
+.Dq Li N
+represents the ASCII decimal value for
+.Dq Li x ) .
+.It Ic cycle_menuitem ( N -- N )
+Cycles menuitem
+.Dq Li N
+between
+.Va menu_caption[x][y]
+entries (where
+.Va N
+represents the ASCII decimal value for
+.Va x ) .
+.El
+.Pp
+For all values of
+.Dq Li x
+above, use any number between 1 through 9. Sorry, double-digits are not
+currently supported.
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/menu.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+A simple boot menu:
+.Pp
+.Bd -literal -offset indent -compact
+include /boot/menu.4th
+menu-init
+set menu_caption[1]="Boot"
+set menu_command[1]="boot"
+set menu_options=2
+set menu_caption[2]="Option: NO"
+set toggled_text[2]="Option: YES"
+set menu_command[2]="toggle_menuitem"
+set menu_timeout_command="boot"
+set menu_reboot
+menu-display
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Xr loader.4th 8 ,
+.Xr beastie.4th 8
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/forth/menu.rc b/sys/boot/forth/menu.rc
new file mode 100644
index 0000000..d8af4b2
--- /dev/null
+++ b/sys/boot/forth/menu.rc
@@ -0,0 +1,76 @@
+\ Menu.rc
+\ $FreeBSD$
+\
+\ Load required Forth modules
+include /boot/version.4th
+include /boot/brand.4th
+include /boot/menu.4th
+include /boot/menu-commands.4th
+include /boot/shortcuts.4th
+
+\ Screen prep
+clear \ clear the screen (see `screen.4th')
+print_version \ print version string (bottom-right; see `version.4th')
+draw-beastie \ draw freebsd mascot (on right; see `beastie.4th')
+draw-brand \ draw the FreeBSD title (top-left; see `brand.4th')
+menu-init \ initialize the menu area (see `menu.4th')
+
+\ Initialize main menu constructs (see `menu.4th')
+\ NOTE: To use the `ansi' variants, add `loader_color=1' to loader.conf(5)
+
+set menu_caption[1]="Boot [ENTER]"
+set menu_command[1]="boot"
+set ansi_caption[1]="Boot [ENTER]"
+set menu_keycode[1]="98"
+
+set menu_caption[2]="[Esc]ape to loader prompt"
+set menu_command[2]="goto_prompt"
+set menu_keycode[2]="27"
+set ansi_caption[2]="Escape to loader prompt"
+
+\ Enable built-in "Reboot" trailing menuitem
+\ NOTE: appears before menu_options if configured
+\
+set menu_reboot
+
+\ Enable "Options:" separator. When set to a numerical value (1-8), a visual
+\ separator is inserted before that menuitem number.
+\
+set menu_options=4
+
+set menu_caption[4]="[A]CPI Support: Disabled"
+set toggled_text[4]="[A]CPI Support: Enabled"
+set menu_command[4]="toggle_acpi"
+set menu_keycode[4]="97"
+set menu_acpi=4
+set ansi_caption[4]="ACPI Support: Disabled"
+set toggled_ansi[4]="ACPI Support: Enabled"
+
+set menu_caption[5]="Boot Safe [M]ode: NO"
+set toggled_text[5]="Boot Safe [M]ode: YES"
+set menu_command[5]="toggle_safemode"
+set menu_keycode[5]="109"
+set ansi_caption[5]="Boot Safe Mode: NO"
+set toggled_ansi[5]="Boot Safe Mode: YES"
+
+set menu_caption[6]="Boot [S]ingle User: NO"
+set toggled_text[6]="Boot [S]ingle User: YES"
+set menu_command[6]="toggle_singleuser"
+set menu_keycode[6]="115"
+set ansi_caption[6]="Boot Single User: NO"
+set toggled_ansi[6]="Boot Single User: YES"
+
+set menu_caption[7]="Boot [V]erbose: NO"
+set toggled_text[7]="Boot [V]erbose: YES"
+set menu_command[7]="toggle_verbose"
+set menu_keycode[7]="118"
+set ansi_caption[7]="Boot Verbose: NO"
+set toggled_ansi[7]="Boot Verbose: YES"
+
+\ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to
+\ customize the timeout; default is 10-seconds)
+\
+set menu_timeout_command="boot"
+
+\ Display the main menu (see `menu.4th')
+menu-display
diff --git a/sys/boot/forth/shortcuts.4th b/sys/boot/forth/shortcuts.4th
new file mode 100644
index 0000000..55a369b
--- /dev/null
+++ b/sys/boot/forth/shortcuts.4th
@@ -0,0 +1,50 @@
+\ Copyright (c) 2008-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+\ FICL words intended to be used as shortcuts for carrying out common tasks or
+\ producing common results. Generally, words defined here are simply groupings
+\ of other custom words that pull from multiple libraries (for example, if you
+\ want to define a custom word that uses words defined in three different
+\ libraries, this is a good place to define such a word).
+\
+\ This script should be included after you have included any/all other
+\ libraries. This will prevent calling a word defined here before any required
+\ words have been defined.
+
+marker task-shortcuts.4th
+
+\ This "shortcut" word will not be used directly, but is defined here to
+\ offer the user a quick way to get back into the interactive PXE menu
+\ after they have escaped to the shell (perhaps by accident).
+\
+: menu ( -- )
+ clear \ Clear the screen (in screen.4th)
+ print_version \ print version string (bottom-right; see version.4th)
+ draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
+ draw-brand \ Draw FIS logo at top (in brand.4th)
+ menu-init \ Initialize menu and draw bounding box (in menu.4th)
+ menu-display \ Launch interactive menu (in menu.4th)
+;
diff --git a/sys/boot/forth/support.4th b/sys/boot/forth/support.4th
index 5484e06..3dbeae8 100644
--- a/sys/boot/forth/support.4th
+++ b/sys/boot/forth/support.4th
@@ -54,7 +54,6 @@
\ Exported global variables;
\
\ string conf_files configuration files to be loaded
-\ string password password
\ cell modules_options pointer to first module information
\ value verbose? indicates if user wants a verbose loading
\ value any_conf_read? indicates if a conf file was succesfully read
@@ -164,7 +163,6 @@ structure: file_metadata
string conf_files
string nextboot_conf_file
-string password
create module_options sizeof module.next allot 0 module_options !
create last_module_option sizeof module.next allot 0 last_module_option !
0 value verbose?
@@ -610,8 +608,6 @@ only forth also support-functions also file-processing definitions also
: execute? s" exec" assignment_type? ;
-: password? s" password" assignment_type? ;
-
: module_load? load_module_suffix suffix_type? ;
: module_loadname? module_loadname_suffix suffix_type? ;
@@ -752,10 +748,6 @@ only forth also support-functions also file-processing definitions also
['] evaluate catch if EEXEC throw then
;
-: set_password
- value_buffer strget unquote password string=
-;
-
: process_assignment
name_buffer .len @ 0= if exit then
loader_conf_files? if set_conf_files exit then
@@ -763,7 +755,6 @@ only forth also support-functions also file-processing definitions also
nextboot_conf? if set_nextboot_conf exit then
verbose_flag? if set_verbose exit then
execute? if execute_command exit then
- password? if set_password exit then
module_load? if set_module_flag exit then
module_loadname? if set_module_loadname exit then
module_type? if set_module_type exit then
@@ -1532,30 +1523,6 @@ also builtins
?dup 0= if ['] load_modules catch then
;
-\ read and store only as many bytes as we need, drop the extra
-: read-password { size | buf len -- }
- size allocate if ENOMEM throw then
- to buf
- 0 to len
- begin
- key
- dup backspace = if
- drop
- len if
- backspace emit bl emit backspace emit
- len 1 - to len
- else
- bell emit
- then
- else
- dup <cr> = if cr drop buf len exit then
- [char] * emit
- len size < if buf len chars + c! else drop then
- len 1+ to len
- then
- again
-;
-
\ Go back to straight forth vocabulary
only forth also definitions
diff --git a/sys/boot/forth/version.4th b/sys/boot/forth/version.4th
new file mode 100644
index 0000000..c59f825
--- /dev/null
+++ b/sys/boot/forth/version.4th
@@ -0,0 +1,60 @@
+\ Copyright (c) 2006-2011 Devin Teske <devinteske@hotmail.com>
+\ All rights reserved.
+\
+\ Redistribution and use in source and binary forms, with or without
+\ modification, are permitted provided that the following conditions
+\ are met:
+\ 1. Redistributions of source code must retain the above copyright
+\ notice, this list of conditions and the following disclaimer.
+\ 2. Redistributions in binary form must reproduce the above copyright
+\ notice, this list of conditions and the following disclaimer in the
+\ documentation and/or other materials provided with the distribution.
+\
+\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+\ SUCH DAMAGE.
+\
+\ $FreeBSD$
+
+marker task-version.4th
+
+variable versionX
+variable versionY
+
+\ Initialize text placement to defaults
+80 versionX ! \ NOTE: this is the ending column (text is right-justified)
+24 versionY !
+
+: print_version ( -- )
+
+ \ Get the text placement position (if set)
+ s" loader_version_x" getenv dup -1 <> if
+ ?number drop versionX ! -1
+ then drop
+ s" loader_version_y" getenv dup -1 <> if
+ ?number drop versionY ! -1
+ then drop
+
+ \ Exit if a version was not set
+ s" loader_version" getenv dup -1 = if
+ drop exit
+ then
+
+ \ Right justify the text
+ dup versionX @ swap - versionY @ at-xy
+
+ \ Print the version (optionally in cyan)
+ loader_color? if
+ ." " type ." "
+ else
+ type
+ then
+;
diff --git a/sys/boot/forth/version.4th.8 b/sys/boot/forth/version.4th.8
new file mode 100644
index 0000000..fff2268
--- /dev/null
+++ b/sys/boot/forth/version.4th.8
@@ -0,0 +1,126 @@
+.\" Copyright (c) 2011 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 19, 2011
+.Dt VERSION.4TH 8
+.Os
+.Sh NAME
+.Nm version.4th
+.Nd FreeBSD version string boot module.
+.Sh DESCRIPTION
+The file that goes by the name of
+.Nm
+is a set of commands designed to draw the boot loader
+version at the bottom-right of the screen.
+The commands of
+.Nm
+by themselves are not enough for most uses.
+Please refer to the
+examples below for the most common situations, and to
+.Xr loader 8
+for additional commands.
+.Pp
+Before using any of the commands provided in
+.Nm ,
+it must be included
+through the command:
+.Pp
+.Dl include version.4th
+.Pp
+This line is present in the default
+.Pa /boot/menu.rc
+file, so it is not needed (and should not be re-issued) in a normal setup.
+.Pp
+The commands provided by it are:
+.Pp
+.Bl -tag -width disable-module_module -compact -offset indent
+.It Ic print_version
+Prints the contents of the
+.Va loader_version
+environment variable right-justified at the column
+.Va loader_version_x
+and row
+.Va loader_version_y .
+.El
+.Pp
+The environment variables that effect its behavior are:
+.Bl -tag -width bootfile -offset indent
+.It Va loader_version
+Set automatically by
+.Xr loader 8 ,
+but you can override it by setting in
+.Xr loader.conf 5 .
+This should be the version of boot loader used.
+.It Va loader_version_x
+Sets the desired ending column position of
+.Va loader_version .
+Default is 80.
+.It Va loader_version_y
+Sets the desired ending row position of
+.Va loader_version .
+Default is 24.
+.It Va loader_color
+If set to
+.Dq Li YES
+(case-insensitive) or
+.Dq Li 1 ,
+causes the version to be printed in ANSI Cyan.
+.El
+.Sh FILES
+.Bl -tag -width /boot/loader.4th -compact
+.It Pa /boot/loader
+The
+.Xr loader 8 .
+.It Pa /boot/version.4th
+.Nm
+itself.
+.It Pa /boot/loader.rc
+.Xr loader 8
+bootstrapping script.
+.El
+.Sh EXAMPLES
+Override
+.Xr loader 8
+version in
+.Xr loader.conf 5 :
+.Pp
+.Bd -literal -offset indent -compact
+loader_version="loader 1.1"
+.Ed
+.Sh SEE ALSO
+.Xr loader.conf 5 ,
+.Xr loader 8 ,
+.Sh HISTORY
+The
+.Nm
+set of commands first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+The
+.Nm
+set of commands was written by
+.An -nosplit
+.An Devin Teske Aq devinteske@hotmail.com .
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index b834ea0..f4babff 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -104,11 +104,16 @@ FILESMODE_${LOADER}= ${BINMODE} -b
.PATH: ${.CURDIR}/../../forth
FILES+= loader.help loader.4th support.4th loader.conf
FILES+= screen.4th frames.4th beastie.4th
+FILES+= brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
FILESDIR_loader.conf= /boot/defaults
.if !exists(${DESTDIR}/boot/loader.rc)
FILES+= loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
.endif
# XXX crt0.o needs to be first for pxeboot(8) to work
diff --git a/sys/boot/ia64/common/Makefile b/sys/boot/ia64/common/Makefile
index 3204edc..d153612 100644
--- a/sys/boot/ia64/common/Makefile
+++ b/sys/boot/ia64/common/Makefile
@@ -33,9 +33,14 @@ loader.help: help.common
.PATH: ${.CURDIR}/../../forth
FILES+= loader.4th support.4th loader.conf
+FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
.if !exists(${DESTDIR}/boot/loader.rc)
FILES+= loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
FILESDIR_loader.conf= /boot/defaults
.include <bsd.lib.mk>
diff --git a/sys/boot/pc98/loader/Makefile b/sys/boot/pc98/loader/Makefile
index e1f47cd..d289cce 100644
--- a/sys/boot/pc98/loader/Makefile
+++ b/sys/boot/pc98/loader/Makefile
@@ -82,6 +82,8 @@ loader.help: help.common help.pc98
.PATH: ${.CURDIR}/../../forth
FILES= loader loader.help loader.4th support.4th loader.conf
FILES+= screen.4th frames.4th beastie.4th
+FILES+= brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
# XXX INSTALLFLAGS_loader= -b
FILESMODE_loader= ${BINMODE} -b
FILESDIR_loader.conf= /boot/defaults
@@ -90,6 +92,10 @@ FILESDIR_loader.conf= /boot/defaults
FILES+= ${.CURDIR}/../../i386/loader/loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
+
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile
index 776f98e..aab4d15 100644
--- a/sys/boot/powerpc/ofw/Makefile
+++ b/sys/boot/powerpc/ofw/Makefile
@@ -103,10 +103,16 @@ loader.help: help.common help.ofw
.PATH: ${.CURDIR}/../../forth
FILES= loader.help loader.4th support.4th loader.conf
+FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
FILESDIR_loader.conf= /boot/defaults
.if !exists(${DESTDIR}/boot/loader.rc)
FILES+= loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
+
.include <bsd.prog.mk>
diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile
index b3a37be..03cc8de 100644
--- a/sys/boot/powerpc/ps3/Makefile
+++ b/sys/boot/powerpc/ps3/Makefile
@@ -113,10 +113,16 @@ loader.help: help.common help.ps3
.PATH: ${.CURDIR}/../../forth
FILES= loader.help loader.4th support.4th loader.conf
+FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
FILESDIR_loader.conf= /boot/defaults
.if !exists(${DESTDIR}/boot/loader.rc)
FILES+= loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
+
.include <bsd.prog.mk>
diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile
index 46c6baa..038794d 100644
--- a/sys/boot/sparc64/loader/Makefile
+++ b/sys/boot/sparc64/loader/Makefile
@@ -84,10 +84,16 @@ loader.help: help.common help.sparc64
.PATH: ${.CURDIR}/../../forth
FILES= loader.help loader.4th support.4th loader.conf
+FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
+FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
FILESDIR_loader.conf= /boot/defaults
.if !exists(${DESTDIR}/boot/loader.rc)
FILES+= loader.rc
.endif
+.if !exists(${DESTDIR}/boot/menu.rc)
+FILES+= menu.rc
+.endif
+
.include <bsd.prog.mk>
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 42bf6f2..7e72b19 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -150,6 +150,7 @@ powerpc/powermac/macgpio.c optional powermac pci
powerpc/powermac/macio.c optional powermac pci
powerpc/powermac/openpic_macio.c optional powermac pci
powerpc/powermac/platform_powermac.c optional powermac
+powerpc/powermac/powermac_thermal.c optional powermac
powerpc/powermac/pswitch.c optional powermac pswitch
powerpc/powermac/pmu.c optional powermac pmu
powerpc/powermac/smu.c optional powermac smu
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
index daee414..fdf1f96 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
@@ -439,9 +439,14 @@ ar9287FillCapabilityInfo(struct ath_hal *ah)
/* Disable this so Block-ACK works correctly */
pCap->halHasRxSelfLinkedTail = AH_FALSE;
pCap->halPSPollBroken = AH_FALSE;
+
+ /* Hardware supports (at least) single-stream STBC TX/RX */
pCap->halRxStbcSupport = 1;
pCap->halTxStbcSupport = 1;
+ /* Hardware supports short-GI w/ 20MHz */
+ pCap->halHTSGI20Support = 1;
+
return AH_TRUE;
}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
index 34a723a..a799ba0 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
@@ -185,6 +185,7 @@ ar9287SetPowerPerRateTable(struct ath_hal *ah,
break;
case 2:
scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ break;
default:
return AH_FALSE; /* Unsupported number of chains */
}
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 745a0d5..5527098 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -627,13 +627,22 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
| IEEE80211_HTC_AMPDU /* A-MPDU tx/rx */
| IEEE80211_HTC_AMSDU /* A-MSDU tx/rx */
| IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
- /* At the present time, the hardware doesn't support short-GI in 20mhz mode */
-#if 0
- | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */
-#endif
| IEEE80211_HTCAP_SMPS_OFF; /* SM power save off */
;
+ /*
+ * Enable short-GI for HT20 only if the hardware
+ * advertises support.
+ * Notably, anything earlier than the AR9287 doesn't.
+ */
+ if ((ath_hal_getcapability(ah,
+ HAL_CAP_HT20_SGI, 0, NULL) == HAL_OK) &&
+ (wmodes & HAL_MODE_HT20)) {
+ device_printf(sc->sc_dev,
+ "[HT] enabling short-GI in 20MHz mode\n");
+ ic->ic_htcaps |= IEEE80211_HTCAP_SHORTGI20;
+ }
+
if (wmodes & HAL_MODE_HT40)
ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40
| IEEE80211_HTCAP_SHORTGI40;
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index e725889..03b5786 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -1726,11 +1726,13 @@ nfsmout:
* Any usecnt must be decremented by calling nfsv4_relref() before
* calling nfsv4_lock(). It was done this way, so nfsv4_lock() could
* be called in a loop.
- * The last argument is set to indicate if the call slept, iff not NULL.
+ * The isleptp argument is set to indicate if the call slept, iff not NULL
+ * and the mp argument indicates to check for a forced dismount, iff not
+ * NULL.
*/
APPLESTATIC int
nfsv4_lock(struct nfsv4lock *lp, int iwantlock, int *isleptp,
- void *mutex)
+ void *mutex, struct mount *mp)
{
if (isleptp)
@@ -1751,6 +1753,10 @@ nfsv4_lock(struct nfsv4lock *lp, int iwantlock, int *isleptp,
lp->nfslock_lock |= NFSV4LOCK_LOCKWANTED;
}
while (lp->nfslock_lock & (NFSV4LOCK_LOCK | NFSV4LOCK_LOCKWANTED)) {
+ if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
+ lp->nfslock_lock &= ~NFSV4LOCK_LOCKWANTED;
+ return (0);
+ }
lp->nfslock_lock |= NFSV4LOCK_WANTED;
if (isleptp)
*isleptp = 1;
@@ -1801,9 +1807,12 @@ nfsv4_relref(struct nfsv4lock *lp)
* not wait for threads that want the exclusive lock. If priority needs
* to be given to threads that need the exclusive lock, a call to nfsv4_lock()
* with the 2nd argument == 0 should be done before calling nfsv4_getref().
+ * If the mp argument is not NULL, check for MNTK_UNMOUNTF being set and
+ * return without getting a refcnt for that case.
*/
APPLESTATIC void
-nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex)
+nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex,
+ struct mount *mp)
{
if (isleptp)
@@ -1813,12 +1822,16 @@ nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex)
* Wait for a lock held.
*/
while (lp->nfslock_lock & NFSV4LOCK_LOCK) {
+ if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
+ return;
lp->nfslock_lock |= NFSV4LOCK_WANTED;
if (isleptp)
*isleptp = 1;
(void) nfsmsleep(&lp->nfslock_lock, mutex,
PZERO - 1, "nfsv4lck", NULL);
}
+ if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
+ return;
lp->nfslock_usecnt++;
}
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index d83d523..8ed60a7 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -247,10 +247,10 @@ int nfsv4_loadattr(struct nfsrv_descript *, vnode_t,
struct nfsv3_pathconf *, struct statfs *, struct nfsstatfs *,
struct nfsfsinfo *, NFSACL_T *,
int, int *, u_int32_t *, u_int32_t *, NFSPROC_T *, struct ucred *);
-int nfsv4_lock(struct nfsv4lock *, int, int *, void *);
+int nfsv4_lock(struct nfsv4lock *, int, int *, void *, struct mount *);
void nfsv4_unlock(struct nfsv4lock *, int);
void nfsv4_relref(struct nfsv4lock *);
-void nfsv4_getref(struct nfsv4lock *, int *, void *);
+void nfsv4_getref(struct nfsv4lock *, int *, void *, struct mount *);
int nfsv4_getref_nonblock(struct nfsv4lock *);
int nfsv4_testlock(struct nfsv4lock *);
int nfsrv_mtostr(struct nfsrv_descript *, char *, int);
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index 6866a73..c7fd69b 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -482,7 +482,7 @@ nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
int igotlock;
do {
- igotlock = nfsv4_lock(lckp, 1, NULL, mutex);
+ igotlock = nfsv4_lock(lckp, 1, NULL, mutex, NULL);
} while (!igotlock);
}
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 8e9aa6a..86d71b6 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -687,11 +687,14 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
struct nfsclclient *clp;
struct nfsclclient *newclp = NULL;
struct nfscllockowner *lp, *nlp;
- struct nfsmount *nmp = VFSTONFS(vnode_mount(vp));
+ struct mount *mp;
+ struct nfsmount *nmp;
char uuid[HOSTUUIDLEN];
int igotlock = 0, error, trystalecnt, clidinusedelay, i;
u_int16_t idlen = 0;
+ mp = vnode_mount(vp);
+ nmp = VFSTONFS(mp);
if (cred != NULL) {
getcredhostuuid(cred, uuid, sizeof uuid);
idlen = strlen(uuid);
@@ -704,6 +707,17 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
M_WAITOK);
}
NFSLOCKCLSTATE();
+ /*
+ * If a forced dismount is already in progress, don't
+ * allocate a new clientid and get out now. For the case where
+ * clp != NULL, this is a harmless optimization.
+ */
+ if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
+ NFSUNLOCKCLSTATE();
+ if (newclp != NULL)
+ free(newclp, M_NFSCLCLIENT);
+ return (EBADF);
+ }
clp = nmp->nm_clp;
if (clp == NULL) {
if (newclp == NULL) {
@@ -736,9 +750,21 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
NFSLOCKCLSTATE();
while ((clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID) == 0 && !igotlock)
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
- NFSCLSTATEMUTEXPTR);
+ NFSCLSTATEMUTEXPTR, mp);
if (!igotlock)
- nfsv4_getref(&clp->nfsc_lock, NULL, NFSCLSTATEMUTEXPTR);
+ nfsv4_getref(&clp->nfsc_lock, NULL, NFSCLSTATEMUTEXPTR, mp);
+ if (igotlock == 0 && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
+ /*
+ * Both nfsv4_lock() and nfsv4_getref() know to check
+ * for MNTK_UNMOUNTF and return without sleeping to
+ * wait for the exclusive lock to be released, since it
+ * might be held by nfscl_umount() and we need to get out
+ * now for that case and not wait until nfscl_umount()
+ * releases it.
+ */
+ NFSUNLOCKCLSTATE();
+ return (EBADF);
+ }
NFSUNLOCKCLSTATE();
/*
@@ -1713,6 +1739,7 @@ nfscl_cleanupkext(struct nfsclclient *clp)
}
#endif /* APPLEKEXT || __FreeBSD__ */
+static int fake_global; /* Used to force visibility of MNTK_UNMOUNTF */
/*
* Called from nfs umount to free up the clientid.
*/
@@ -1723,6 +1750,33 @@ nfscl_umount(struct nfsmount *nmp, NFSPROC_T *p)
struct ucred *cred;
int igotlock;
+ /*
+ * For the case that matters, this is the thread that set
+ * MNTK_UNMOUNTF, so it will see it set. The code that follows is
+ * done to ensure that any thread executing nfscl_getcl() after
+ * this time, will see MNTK_UNMOUNTF set. nfscl_getcl() uses the
+ * mutex for NFSLOCKCLSTATE(), so it is "m" for the following
+ * explanation, courtesy of Alan Cox.
+ * What follows is a snippet from Alan Cox's email at:
+ * http://docs.FreeBSD.org/cgi/
+ * mid.cgi?BANLkTikR3d65zPHo9==08ZfJ2vmqZucEvw
+ *
+ * 1. Set MNTK_UNMOUNTF
+ * 2. Acquire a standard FreeBSD mutex "m".
+ * 3. Update some data structures.
+ * 4. Release mutex "m".
+ *
+ * Then, other threads that acquire "m" after step 4 has occurred will
+ * see MNTK_UNMOUNTF as set. But, other threads that beat thread X to
+ * step 2 may or may not see MNTK_UNMOUNTF as set.
+ */
+ NFSLOCKCLSTATE();
+ if ((nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
+ fake_global++;
+ NFSUNLOCKCLSTATE();
+ NFSLOCKCLSTATE();
+ }
+
clp = nmp->nm_clp;
if (clp != NULL) {
if ((clp->nfsc_flags & NFSCLFLAGS_INITED) == 0)
@@ -1734,12 +1788,16 @@ nfscl_umount(struct nfsmount *nmp, NFSPROC_T *p)
*/
clp->nfsc_flags |= NFSCLFLAGS_UMOUNT;
while (clp->nfsc_flags & NFSCLFLAGS_HASTHREAD)
- (void) tsleep((caddr_t)clp, PWAIT, "nfsclumnt", hz);
+ (void)mtx_sleep(clp, NFSCLSTATEMUTEXPTR, PWAIT,
+ "nfsclumnt", hz);
- NFSLOCKCLSTATE();
+ /*
+ * Now, get the exclusive lock on the client state, so
+ * that no uses of the state are still in progress.
+ */
do {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
- NFSCLSTATEMUTEXPTR);
+ NFSCLSTATEMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKCLSTATE();
@@ -1756,8 +1814,8 @@ nfscl_umount(struct nfsmount *nmp, NFSPROC_T *p)
nmp->nm_clp = NULL;
NFSFREECRED(cred);
FREE((caddr_t)clp, M_NFSCLCLIENT);
- }
-
+ } else
+ NFSUNLOCKCLSTATE();
}
/*
@@ -1790,7 +1848,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
do {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
- NFSCLSTATEMUTEXPTR);
+ NFSCLSTATEMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKCLSTATE();
@@ -2105,7 +2163,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
clp->nfsc_flags |= NFSCLFLAGS_EXPIREIT;
do {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
- NFSCLSTATEMUTEXPTR);
+ NFSCLSTATEMUTEXPTR, NULL);
} while (!igotlock && (clp->nfsc_flags & NFSCLFLAGS_EXPIREIT));
if ((clp->nfsc_flags & NFSCLFLAGS_EXPIREIT) == 0) {
if (igotlock)
@@ -2464,7 +2522,7 @@ tryagain:
}
while (!igotlock) {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
- &islept, NFSCLSTATEMUTEXPTR);
+ &islept, NFSCLSTATEMUTEXPTR, NULL);
if (islept)
goto tryagain;
}
@@ -2556,14 +2614,18 @@ tryagain:
}
#endif /* APPLEKEXT || __FreeBSD__ */
+ NFSLOCKCLSTATE();
if ((clp->nfsc_flags & NFSCLFLAGS_RECOVER) == 0)
- (void) tsleep((caddr_t)clp, PWAIT, "nfscl", hz);
+ (void)mtx_sleep(clp, NFSCLSTATEMUTEXPTR, PWAIT, "nfscl",
+ hz);
if (clp->nfsc_flags & NFSCLFLAGS_UMOUNT) {
- NFSFREECRED(cred);
clp->nfsc_flags &= ~NFSCLFLAGS_HASTHREAD;
+ NFSUNLOCKCLSTATE();
+ NFSFREECRED(cred);
wakeup((caddr_t)clp);
return;
}
+ NFSUNLOCKCLSTATE();
}
}
@@ -3864,7 +3926,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
islept = 0;
while (!igotlock) {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
- &islept, NFSCLSTATEMUTEXPTR);
+ &islept, NFSCLSTATEMUTEXPTR, NULL);
if (islept)
break;
}
@@ -3963,7 +4025,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
islept = 0;
while (!igotlock) {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
- &islept, NFSCLSTATEMUTEXPTR);
+ &islept, NFSCLSTATEMUTEXPTR, NULL);
if (islept)
break;
}
@@ -4043,7 +4105,7 @@ nfscl_getref(struct nfsmount *nmp)
NFSUNLOCKCLSTATE();
return (0);
}
- nfsv4_getref(&clp->nfsc_lock, NULL, NFSCLSTATEMUTEXPTR);
+ nfsv4_getref(&clp->nfsc_lock, NULL, NFSCLSTATEMUTEXPTR, NULL);
NFSUNLOCKCLSTATE();
return (1);
}
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index eeecded..7007275 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -525,10 +525,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
NFSLOCKV4ROOTMUTEX();
if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
else
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
if (igotlock) {
/*
@@ -576,7 +576,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
*/
NFSLOCKV4ROOTMUTEX();
nfsv4_getref(&nfsv4rootfs_lock, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
}
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index ab94f0e..fc84d72 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -169,7 +169,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
@@ -419,7 +419,7 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
} else if (opflags != CLOPS_RENEW) {
@@ -548,7 +548,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
NFSLOCKV4ROOTMUTEX();
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
@@ -608,7 +608,7 @@ nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt)
* exclusive lock cannot be acquired while dumping the clients.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
NFSLOCKSTATE();
/*
@@ -709,7 +709,7 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt,
* exclusive lock on it cannot be acquired while dumping the locks.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
NFSLOCKSTATE();
if (!ret)
@@ -4254,7 +4254,7 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
@@ -4422,7 +4422,7 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
nfsv4_relref(&nfsv4rootfs_lock);
do {
gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
@@ -4616,7 +4616,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
* exclusive lock cannot be acquired by another thread.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
/*
@@ -5179,7 +5179,7 @@ nfsrv_locklf(struct nfslockfile *lfp)
lfp->lf_usecount++;
do {
gotlock = nfsv4_lock(&lfp->lf_locallock_lck, 1, NULL,
- NFSSTATEMUTEXPTR);
+ NFSSTATEMUTEXPTR, NULL);
} while (gotlock == 0);
lfp->lf_usecount--;
}
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 98bd9c5..01f7777 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -104,8 +104,6 @@ SDT_PROBE_DEFINE2(racct, kernel, racct, leave, leave, "struct racct *",
int racct_types[] = {
[RACCT_CPU] =
RACCT_IN_THOUSANDS,
- [RACCT_FSIZE] =
- RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
[RACCT_DATA] =
RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
[RACCT_STACK] =
@@ -120,8 +118,6 @@ int racct_types[] = {
RACCT_RECLAIMABLE | RACCT_DENIABLE,
[RACCT_NOFILE] =
RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
- [RACCT_SBSIZE] =
- RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
[RACCT_VMEM] =
RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
[RACCT_NPTS] =
@@ -627,7 +623,6 @@ racct_proc_exit(struct proc *p)
/*
* XXX: Free this some other way.
*/
- racct_set(p, RACCT_FSIZE, 0);
racct_set(p, RACCT_NPTS, 0);
racct_set(p, RACCT_NTHR, 0);
racct_set(p, RACCT_RSS, 0);
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c
index 2d43bdc..3d0a478 100644
--- a/sys/kern/kern_rctl.c
+++ b/sys/kern/kern_rctl.c
@@ -100,7 +100,6 @@ static struct dict subjectnames[] = {
static struct dict resourcenames[] = {
{ "cpu", RACCT_CPU },
- { "fsize", RACCT_FSIZE },
{ "data", RACCT_DATA },
{ "stack", RACCT_STACK },
{ "core", RACCT_CORE },
@@ -108,7 +107,6 @@ static struct dict resourcenames[] = {
{ "memlock", RACCT_MEMLOCK },
{ "nproc", RACCT_NPROC },
{ "nofile", RACCT_NOFILE },
- { "sbsize", RACCT_SBSIZE },
{ "vmem", RACCT_VMEM },
{ "npts", RACCT_NPTS },
{ "swap", RACCT_SWAP },
diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S
index 3ac4a1a..de7effc 100644
--- a/sys/powerpc/booke/locore.S
+++ b/sys/powerpc/booke/locore.S
@@ -83,17 +83,18 @@ __start:
* locore registers use:
* r1 : stack pointer
* r2 : trace pointer (AP only, for early diagnostics)
- * r3-r27 : scratch registers
- * r28 : kernload
- * r29 : temp TLB1 entry
- * r30 : initial TLB1 entry we started in
- * r31 : metadata pointer
+ * r3-r26 : scratch registers
+ * r27 : kernload
+ * r28 : temp TLB1 entry
+ * r29 : initial TLB1 entry we started in
+ * r30-r31 : arguments (metadata pointer)
*/
/*
- * Keep metadata ptr in r31 for later use.
+ * Keep arguments in r30 & r31 for later use.
*/
- mr %r31, %r3
+ mr %r30, %r3
+ mr %r31, %r4
/*
* Initial cleanup
@@ -120,7 +121,7 @@ __start:
*/
bl 1f
1: mflr %r3
- bl tlb1_find_current /* the entry number found is returned in r30 */
+ bl tlb1_find_current /* the entry found is returned in r29 */
bl tlb1_inval_all_but_current
/*
@@ -140,7 +141,7 @@ __start:
/*
* Invalidate initial entry
*/
- mr %r3, %r30
+ mr %r3, %r29
bl tlb1_inval_entry
/*
@@ -148,7 +149,7 @@ __start:
*/
/* Final kernel mapping, map in 16 MB of RAM */
lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */
- li %r4, 1 /* Entry 1 */
+ li %r4, 0 /* Entry 0 */
rlwimi %r3, %r4, 16, 12, 15
mtspr SPR_MAS0, %r3
isync
@@ -170,7 +171,7 @@ __start:
bl 3f
3: mflr %r4 /* Use current address */
rlwinm %r4, %r4, 0, 0, 7 /* 16MB alignment mask */
- mr %r28, %r4 /* Keep kernel load address */
+ mr %r27, %r4 /* Keep kernel load address */
ori %r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l
mtspr SPR_MAS3, %r4 /* Set RPN and protection */
isync
@@ -193,7 +194,7 @@ __start:
/*
* Invalidate temp mapping
*/
- mr %r3, %r29
+ mr %r3, %r28
bl tlb1_inval_entry
/*
@@ -201,7 +202,7 @@ __start:
*/
lis %r3, kernload@ha
addi %r3, %r3, kernload@l
- stw %r28, 0(%r3)
+ stw %r27, 0(%r3)
#ifdef SMP
/*
* APs need a separate copy of kernload info within the __boot_page
@@ -210,7 +211,7 @@ __start:
*/
lis %r3, kernload_ap@ha
addi %r3, %r3, kernload_ap@l
- stw %r28, 0(%r3)
+ stw %r27, 0(%r3)
msync
#endif
@@ -229,14 +230,11 @@ __start:
/*
* Set up arguments and jump to system initialization code
*/
- lis %r3, kernel_text@ha
- addi %r3, %r3, kernel_text@l
- lis %r4, _end@ha
- addi %r4, %r4, _end@l
- mr %r5, %r31 /* metadata ptr */
+ mr %r3, %r30
+ mr %r4, %r31
/* Prepare e500 core */
- bl e500_init
+ bl booke_init
/* Switch to thread0.td_kstack now */
mr %r1, %r3
@@ -290,7 +288,7 @@ kernload_ap:
*/
bl 2f
2: mflr %r3
- bl tlb1_find_current /* the entry number found is in r30 */
+ bl tlb1_find_current /* the entry number found is in r29 */
bl tlb1_inval_all_but_current
/*
@@ -310,7 +308,7 @@ kernload_ap:
/*
* Invalidate initial entry
*/
- mr %r3, %r30
+ mr %r3, %r29
bl tlb1_inval_entry
/*
@@ -318,7 +316,7 @@ kernload_ap:
*/
/* Final kernel mapping, map in 16 MB of RAM */
lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */
- li %r4, 1 /* Entry 1 */
+ li %r4, 0 /* Entry 0 */
rlwimi %r3, %r4, 16, 4, 15
mtspr SPR_MAS0, %r3
isync
@@ -373,7 +371,7 @@ kernload_ap:
/*
* Invalidate temp mapping
*/
- mr %r3, %r29
+ mr %r3, %r28
bl tlb1_inval_entry
/*
@@ -425,7 +423,7 @@ tlb_inval_all:
blr
/*
- * expects address to look up in r3, returns entry number in r30
+ * expects address to look up in r3, returns entry number in r29
*
* FIXME: the hidden assumption is we are now running in AS=0, but we should
* retrieve actual AS from MSR[IS|DS] and put it in MAS6[SAS]
@@ -437,7 +435,7 @@ tlb1_find_current:
isync
tlbsx 0, %r3
mfspr %r17, SPR_MAS0
- rlwinm %r30, %r17, 16, 20, 31 /* MAS0[ESEL] -> r30 */
+ rlwinm %r29, %r17, 16, 20, 31 /* MAS0[ESEL] -> r29 */
/* Make sure we have IPROT set on the entry */
mfspr %r17, SPR_MAS1
@@ -470,14 +468,14 @@ tlb1_inval_entry:
blr
/*
- * r30 current entry number
- * r29 returned temp entry
+ * r29 current entry number
+ * r28 returned temp entry
* r3-r5 scratched
*/
tlb1_temp_mapping_as1:
/* Read our current translation */
lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */
- rlwimi %r3, %r30, 16, 12, 15 /* Select our current entry */
+ rlwimi %r3, %r29, 16, 12, 15 /* Select our current entry */
mtspr SPR_MAS0, %r3
isync
tlbre
@@ -489,12 +487,8 @@ tlb1_temp_mapping_as1:
* entry is the last in TLB1
*/
lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */
- addi %r29, %r30, 1 /* Use next entry. */
- li %r4, 1
- cmpw %r4, %r29
- bne 1f
- addi %r29, %r29, 1
-1: rlwimi %r3, %r29, 16, 12, 15 /* Select temp entry */
+ addi %r28, %r29, 1 /* Use next entry. */
+ rlwimi %r3, %r28, 16, 12, 15 /* Select temp entry */
mtspr SPR_MAS0, %r3
isync
mfspr %r5, SPR_MAS1
@@ -514,7 +508,7 @@ tlb1_temp_mapping_as1:
* Loops over TLB1, invalidates all entries skipping the one which currently
* maps this code.
*
- * r30 current entry
+ * r29 current entry
* r3-r5 scratched
*/
tlb1_inval_all_but_current:
@@ -528,7 +522,7 @@ tlb1_inval_all_but_current:
isync
tlbre
mfspr %r5, SPR_MAS1
- cmpw %r4, %r30 /* our current entry? */
+ cmpw %r4, %r29 /* our current entry? */
beq 2f
rlwinm %r5, %r5, 0, 2, 31 /* clear VALID and IPROT bits */
mtspr SPR_MAS1, %r5
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index f2dbacf..c2b5e6f 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -190,7 +190,7 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL);
void print_kernel_section_addr(void);
void print_kenv(void);
-u_int e500_init(u_int32_t, u_int32_t, void *);
+u_int booke_init(uint32_t, uint32_t);
static void
cpu_e500_startup(void *dummy)
@@ -276,19 +276,41 @@ print_kernel_section_addr(void)
}
u_int
-e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
+booke_init(uint32_t arg1, uint32_t arg2)
{
struct pcpu *pc;
- void *kmdp;
+ void *kmdp, *mdp;
vm_offset_t dtbp, end;
uint32_t csr;
kmdp = NULL;
- end = endkernel;
+ end = (uintptr_t)_end;
dtbp = (vm_offset_t)NULL;
/*
+ * Handle the various ways we can get loaded and started:
+ * - FreeBSD's loader passes the pointer to the metadata
+ * in arg1, with arg2 undefined. arg1 has a value that's
+ * relative to the kernel's link address (i.e. larger
+ * than 0xc0000000).
+ * - Juniper's loader passes the metadata pointer in arg2
+ * and sets arg1 to zero. This is to signal that the
+ * loader maps the kernel and starts it at its link
+ * address (unlike the FreeBSD loader).
+ * - U-Boot passes the standard argc and argv parameters
+ * in arg1 and arg2 (resp). arg1 is between 1 and some
+ * relatively small number, such as 64K. arg2 is the
+ * physical address of the argv vector.
+ */
+ if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */
+ mdp = (void *)arg1;
+ else if (arg1 == 0) /* Juniper loader */
+ mdp = (void *)arg2;
+ else /* U-Boot */
+ mdp = NULL;
+
+ /*
* Parse metadata and fetch parameters.
*/
if (mdp != NULL) {
@@ -309,17 +331,8 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
#endif
}
} else {
- /*
- * We should scream but how? Cannot even output anything...
- */
-
- /*
- * FIXME add return value and handle in the locore so we can
- * return to the loader maybe? (this seems not very easy to
- * restore everything as the TLB have all been reprogrammed
- * in the locore etc...)
- */
- while (1);
+ bzero(__sbss_start, __sbss_end - __sbss_start);
+ bzero(__bss_start, _end - __bss_start);
}
#if defined(FDT_DTB_STATIC)
@@ -368,9 +381,7 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
cninit();
/* Print out some debug info... */
- debugf("e500_init: console initialized\n");
- debugf(" arg1 startkernel = 0x%08x\n", startkernel);
- debugf(" arg2 endkernel = 0x%08x\n", endkernel);
+ debugf("%s: console initialized\n", __func__);
debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp);
debugf(" end = 0x%08x\n", (u_int32_t)end);
debugf(" boothowto = 0x%08x\n", boothowto);
@@ -403,7 +414,7 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
/* Initialise virtual memory. */
pmap_mmu_install(MMU_TYPE_BOOKE, 0);
- pmap_bootstrap(startkernel, end);
+ pmap_bootstrap((uintptr_t)kernel_text, end);
debugf("MSR = 0x%08x\n", mfmsr());
//tlb1_print_entries();
//tlb1_print_tlbentries();
@@ -449,8 +460,8 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp)
printf("L1 I-cache %sabled\n",
(csr & L1CSR1_ICE) ? "en" : "dis");
- debugf("e500_init: SP = 0x%08x\n", ((uintptr_t)thread0.td_pcb - 16) & ~15);
- debugf("e500_init: e\n");
+ debugf("%s: SP = 0x%08x\n", __func__,
+ ((uintptr_t)thread0.td_pcb - 16) & ~15);
return (((uintptr_t)thread0.td_pcb - 16) & ~15);
}
diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c
index 0fbb98a..d76664e 100644
--- a/sys/powerpc/booke/platform_bare.c
+++ b/sys/powerpc/booke/platform_bare.c
@@ -104,10 +104,22 @@ bare_probe(platform_t plat)
int i, law_max, tgt;
ver = SVR_VER(mfspr(SPR_SVR));
- if (ver == SVR_MPC8572E || ver == SVR_MPC8572)
+ switch (ver & ~0x0008) { /* Mask Security Enabled bit */
+ case SVR_P4080:
+ maxcpu = 8;
+ break;
+ case SVR_P4040:
+ maxcpu = 4;
+ break;
+ case SVR_MPC8572:
+ case SVR_P1020:
+ case SVR_P2020:
maxcpu = 2;
- else
+ break;
+ default:
maxcpu = 1;
+ break;
+ }
/*
* Clear local access windows. Skip DRAM entries, so we don't shoot
@@ -280,24 +292,23 @@ bare_smp_start_cpu(platform_t plat, struct pcpu *pc)
static void
e500_reset(platform_t plat)
{
- uint32_t ver = SVR_VER(mfspr(SPR_SVR));
-
- if (ver == SVR_MPC8572E || ver == SVR_MPC8572 ||
- ver == SVR_MPC8548E || ver == SVR_MPC8548)
- /* Systems with dedicated reset register */
- ccsr_write4(OCP85XX_RSTCR, 2);
- else {
- /* Clear DBCR0, disables debug interrupts and events. */
- mtspr(SPR_DBCR0, 0);
- __asm __volatile("isync");
-
- /* Enable Debug Interrupts in MSR. */
- mtmsr(mfmsr() | PSL_DE);
-
- /* Enable debug interrupts and issue reset. */
- mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM |
- DBCR0_RST_SYSTEM);
- }
+
+ /*
+ * Try the dedicated reset register first.
+ * If the SoC doesn't have one, we'll fall
+ * back to using the debug control register.
+ */
+ ccsr_write4(OCP85XX_RSTCR, 2);
+
+ /* Clear DBCR0, disables debug interrupts and events. */
+ mtspr(SPR_DBCR0, 0);
+ __asm __volatile("isync");
+
+ /* Enable Debug Interrupts in MSR. */
+ mtmsr(mfmsr() | PSL_DE);
+
+ /* Enable debug interrupts and issue reset. */
+ mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM);
printf("Reset failed...\n");
while (1);
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 11be68e..81fce09 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -92,9 +92,6 @@ __FBSDID("$FreeBSD$");
#include "mmu_if.h"
-#define DEBUG
-#undef DEBUG
-
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args)
#else
@@ -947,7 +944,7 @@ pte_find(mmu_t mmu, pmap_t pmap, vm_offset_t va)
/**************************************************************************/
/*
- * This is called during e500_init, before the system is really initialized.
+ * This is called during booke_init, before the system is really initialized.
*/
static void
mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
@@ -3022,24 +3019,18 @@ tlb1_init(vm_offset_t ccsrbar)
{
uint32_t mas0;
- /* TLB1[1] is used to map the kernel. Save that entry. */
- mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(1);
+ /* TLB1[0] is used to map the kernel. Save that entry. */
+ mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(0);
mtspr(SPR_MAS0, mas0);
__asm __volatile("isync; tlbre");
- tlb1[1].mas1 = mfspr(SPR_MAS1);
- tlb1[1].mas2 = mfspr(SPR_MAS2);
- tlb1[1].mas3 = mfspr(SPR_MAS3);
+ tlb1[0].mas1 = mfspr(SPR_MAS1);
+ tlb1[0].mas2 = mfspr(SPR_MAS2);
+ tlb1[0].mas3 = mfspr(SPR_MAS3);
- /* Map in CCSRBAR in TLB1[0] */
- tlb1_idx = 0;
+ /* Map in CCSRBAR in TLB1[1] */
+ tlb1_idx = 1;
tlb1_set_entry(CCSRBAR_VA, ccsrbar, CCSRBAR_SIZE, _TLB_ENTRY_IO);
- /*
- * Set the next available TLB1 entry index. Note TLB[1] is reserved
- * for initial mapping of kernel text+data, which was set early in
- * locore, we need to skip this [busy] entry.
- */
- tlb1_idx = 2;
/* Setup TLB miss defaults */
set_mas4_defaults();
diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h
index d71d048..06b131c 100644
--- a/sys/powerpc/include/param.h
+++ b/sys/powerpc/include/param.h
@@ -68,7 +68,7 @@
#endif
#if defined(SMP) || defined(KLD_MODULE)
-#define MAXCPU 4
+#define MAXCPU 8
#else
#define MAXCPU 1
#endif /* SMP || KLD_MODULE */
diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h
index f08f614..4f675c3 100644
--- a/sys/powerpc/include/spr.h
+++ b/sys/powerpc/include/spr.h
@@ -662,6 +662,10 @@
#define SVR_P2010E 0x80eb
#define SVR_P2020 0x80e2
#define SVR_P2020E 0x80ea
+#define SVR_P4040 0x8200
+#define SVR_P4040E 0x8208
+#define SVR_P4080 0x8201
+#define SVR_P4080E 0x8209
#define SVR_VER(svr) (((svr) >> 16) & 0xffff)
#define SPR_PID0 0x030 /* ..8 Process ID Register 0 */
diff --git a/sys/powerpc/mpc85xx/mpc85xx.c b/sys/powerpc/mpc85xx/mpc85xx.c
index 564bf84..f383a1b 100644
--- a/sys/powerpc/mpc85xx/mpc85xx.c
+++ b/sys/powerpc/mpc85xx/mpc85xx.c
@@ -69,12 +69,13 @@ law_getmax(void)
uint32_t ver;
ver = SVR_VER(mfspr(SPR_SVR));
- if (ver == SVR_MPC8572E || ver == SVR_MPC8572)
- return (12);
- else if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
- return (10);
- else
+ if (ver == SVR_MPC8555E || ver == SVR_MPC8555)
return (8);
+ if (ver == SVR_MPC8548E || ver == SVR_MPC8548 ||
+ ver == SVR_MPC8533E || ver == SVR_MPC8533)
+ return (10);
+
+ return (12);
}
#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2))
@@ -152,10 +153,16 @@ law_pci_target(struct resource *res, int *trgt_mem, int *trgt_io)
trgt = 1;
break;
case 0xa000:
- if (ver == SVR_MPC8572E || ver == SVR_MPC8572)
- trgt = 2;
+ if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
+ trgt = 3;
else
+ trgt = 2;
+ break;
+ case 0xb000:
+ if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
rv = EINVAL;
+ else
+ trgt = 3;
break;
default:
rv = ENXIO;
diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h
index 7621f2c..fa3bde3 100644
--- a/sys/powerpc/mpc85xx/mpc85xx.h
+++ b/sys/powerpc/mpc85xx/mpc85xx.h
@@ -67,11 +67,6 @@
#define OCP85XX_PORDEVSR2 (CCSRBAR_VA + 0xe0014)
-#define OCP85XX_DEVDISR (CCSRBAR_VA + 0xe0070)
-#define OCP85XX_DEVDISR_PCIE0 0x20000000
-#define OCP85XX_DEVDISR_PCIE1 0x04000000
-#define OCP85XX_DEVDISR_PCIE2 0x02000000
-
/*
* Status Registers.
*/
diff --git a/sys/powerpc/powermac/powermac_thermal.c b/sys/powerpc/powermac/powermac_thermal.c
new file mode 100644
index 0000000..89637ca
--- /dev/null
+++ b/sys/powerpc/powermac/powermac_thermal.c
@@ -0,0 +1,176 @@
+/*-
+ * Copyright (c) 2009-2011 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+#include <sys/types.h>
+#include <sys/kthread.h>
+#include <sys/malloc.h>
+#include <sys/reboot.h>
+#include <sys/sysctl.h>
+#include <sys/queue.h>
+
+#include "powermac_thermal.h"
+
+static void fan_management_proc(void);
+static void pmac_therm_manage_fans(void);
+
+static struct proc *pmac_them_proc;
+static int enable_pmac_thermal = 1;
+
+static struct kproc_desc pmac_therm_kp = {
+ "pmac_thermal",
+ fan_management_proc,
+ &pmac_them_proc
+};
+
+SYSINIT(pmac_therm_setup, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, kproc_start,
+ &pmac_therm_kp);
+SYSCTL_INT(_machdep, OID_AUTO, manage_fans, CTLFLAG_RW | CTLFLAG_TUN,
+ &enable_pmac_thermal, 1, "Enable automatic fan management");
+MALLOC_DEFINE(M_PMACTHERM, "pmactherm", "Powermac Thermal Management");
+
+struct pmac_fan_le {
+ struct pmac_fan *fan;
+ int last_val;
+ SLIST_ENTRY(pmac_fan_le) entries;
+};
+struct pmac_sens_le {
+ struct pmac_therm *sensor;
+ int last_val;
+ SLIST_ENTRY(pmac_sens_le) entries;
+};
+static SLIST_HEAD(pmac_fans, pmac_fan_le) fans = SLIST_HEAD_INITIALIZER(fans);
+static SLIST_HEAD(pmac_sensors, pmac_sens_le) sensors =
+ SLIST_HEAD_INITIALIZER(sensors);
+
+static void
+fan_management_proc(void)
+{
+ /* Nothing to manage? */
+ if (SLIST_EMPTY(&fans))
+ return;
+
+ while (1) {
+ pmac_therm_manage_fans();
+ pause("pmac_therm", hz);
+ }
+}
+
+static void
+pmac_therm_manage_fans(void)
+{
+ struct pmac_sens_le *sensor;
+ struct pmac_fan_le *fan;
+ int average_excess, max_excess_zone, frac_excess;
+ int nsens, nsens_zone;
+
+ if (!enable_pmac_thermal)
+ return;
+
+ /* Read all the sensors */
+ SLIST_FOREACH(sensor, &sensors, entries) {
+ sensor->last_val = sensor->sensor->read(sensor->sensor);
+ if (sensor->last_val > sensor->sensor->max_temp) {
+ printf("WARNING: Current temperature (%s: %d.%d C) "
+ "exceeds critical temperature (%d.%d C)! "
+ "Shutting down!\n", sensor->sensor->name,
+ sensor->last_val / 10, sensor->last_val % 10,
+ sensor->sensor->max_temp / 10,
+ sensor->sensor->max_temp % 10);
+ shutdown_nice(RB_POWEROFF);
+ }
+ }
+
+ /* Set all the fans */
+ SLIST_FOREACH(fan, &fans, entries) {
+ nsens = nsens_zone = 0;
+ average_excess = max_excess_zone = 0;
+ SLIST_FOREACH(sensor, &sensors, entries) {
+ frac_excess = (sensor->last_val -
+ sensor->sensor->target_temp)*100 /
+ (sensor->sensor->max_temp -
+ sensor->sensor->target_temp);
+ if (sensor->sensor->zone == fan->fan->zone) {
+ max_excess_zone = imax(max_excess_zone,
+ frac_excess);
+ nsens_zone++;
+ }
+ average_excess += frac_excess;
+ nsens++;
+ }
+ average_excess /= nsens;
+
+ /* If there are no sensors in this zone, use the average */
+ if (nsens_zone == 0)
+ max_excess_zone = average_excess;
+ /* No sensors at all? Use default */
+ if (nsens == 0) {
+ fan->fan->set(fan->fan, fan->fan->default_rpm);
+ continue;
+ }
+
+ /*
+ * Scale the fan linearly in the max temperature in its
+ * thermal zone.
+ */
+ fan->fan->set(fan->fan, max_excess_zone *
+ (fan->fan->max_rpm - fan->fan->min_rpm)/100 +
+ fan->fan->min_rpm);
+ }
+}
+
+void
+pmac_thermal_fan_register(struct pmac_fan *fan)
+{
+ struct pmac_fan_le *list_entry;
+
+ list_entry = malloc(sizeof(struct pmac_fan_le), M_PMACTHERM,
+ M_ZERO | M_WAITOK);
+ list_entry->fan = fan;
+
+ SLIST_INSERT_HEAD(&fans, list_entry, entries);
+}
+
+void
+pmac_thermal_sensor_register(struct pmac_therm *sensor)
+{
+ struct pmac_sens_le *list_entry;
+
+ list_entry = malloc(sizeof(struct pmac_sens_le), M_PMACTHERM,
+ M_ZERO | M_WAITOK);
+ list_entry->sensor = sensor;
+
+ SLIST_INSERT_HEAD(&sensors, list_entry, entries);
+}
+
diff --git a/sys/powerpc/powermac/powermac_thermal.h b/sys/powerpc/powermac/powermac_thermal.h
new file mode 100644
index 0000000..43bd629
--- /dev/null
+++ b/sys/powerpc/powermac/powermac_thermal.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2009-2011 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _POWERPC_POWERMAC_POWERMAC_THERMAL_H
+#define _POWERPC_POWERMAC_POWERMAC_THERMAL_H
+
+struct pmac_fan {
+ int min_rpm, max_rpm, default_rpm;
+
+ char name[32];
+ int zone;
+
+ int (*read)(struct pmac_fan *);
+ int (*set)(struct pmac_fan *, int value);
+};
+
+struct pmac_therm {
+ int target_temp, max_temp; /* Tenths of a degree K */
+
+ char name[32];
+ int zone;
+
+ int (*read)(struct pmac_therm *);
+};
+
+void pmac_thermal_fan_register(struct pmac_fan *);
+void pmac_thermal_sensor_register(struct pmac_therm *);
+
+#endif
diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c
index 928472c..09025b1 100644
--- a/sys/powerpc/powermac/smu.c
+++ b/sys/powerpc/powermac/smu.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <powerpc/powermac/macgpiovar.h>
+#include <powerpc/powermac/powermac_thermal.h>
#include "clock_if.h"
#include "iicbus_if.h"
@@ -69,19 +70,19 @@ struct smu_cmd {
STAILQ_HEAD(smu_cmdq, smu_cmd);
struct smu_fan {
+ struct pmac_fan fan;
+ device_t dev;
cell_t reg;
- cell_t min_rpm;
- cell_t max_rpm;
- cell_t unmanaged_rpm;
- char location[32];
int old_style;
int setpoint;
};
struct smu_sensor {
+ struct pmac_therm therm;
+ device_t dev;
+
cell_t reg;
- char location[32];
enum {
SMU_CURRENT_SENSOR,
SMU_VOLTAGE_SENSOR,
@@ -131,10 +132,6 @@ struct smu_softc {
uint16_t sc_slots_pow_scale;
int16_t sc_slots_pow_offset;
- /* Thermal management parameters */
- int sc_target_temp; /* Default 55 C */
- int sc_critical_temp; /* Default 90 C */
-
struct cdev *sc_leddev;
};
@@ -161,8 +158,6 @@ static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf,
static void smu_attach_i2c(device_t dev, phandle_t i2croot);
static void smu_attach_fans(device_t dev, phandle_t fanroot);
static void smu_attach_sensors(device_t dev, phandle_t sensroot);
-static void smu_fan_management_proc(void *xdev);
-static void smu_manage_fans(device_t smu);
static void smu_set_sleepled(void *xdev, int onoff);
static int smu_server_mode(SYSCTL_HANDLER_ARGS);
static void smu_doorbell_intr(void *xdev);
@@ -349,24 +344,6 @@ smu_attach(device_t dev)
sc->sc_slots_pow_offset = (data[6] << 8) + data[7];
/*
- * Set up simple-minded thermal management.
- */
- sc->sc_target_temp = 55;
- sc->sc_critical_temp = 90;
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- "target_temp", CTLTYPE_INT | CTLFLAG_RW, &sc->sc_target_temp,
- sizeof(int), "Target temperature (C)");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- "critical_temp", CTLTYPE_INT | CTLFLAG_RW,
- &sc->sc_critical_temp, sizeof(int), "Critical temperature (C)");
-
- kproc_create(smu_fan_management_proc, dev, &sc->sc_fanmgt_proc,
- RFHIGHPID, 0, "smu_thermal");
-
- /*
* Set up LED interface
*/
sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled");
@@ -658,8 +635,9 @@ doorbell_attach(device_t dev)
*/
static int
-smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
+smu_fan_set_rpm(struct smu_fan *fan, int rpm)
{
+ device_t smu = fan->dev;
struct smu_cmd cmd;
int error;
@@ -667,8 +645,8 @@ smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
error = EIO;
/* Clamp to allowed range */
- rpm = max(fan->min_rpm, rpm);
- rpm = min(fan->max_rpm, rpm);
+ rpm = max(fan->fan.min_rpm, rpm);
+ rpm = min(fan->fan.max_rpm, rpm);
/*
* Apple has two fan control mechanisms. We can't distinguish
@@ -684,7 +662,7 @@ smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
cmd.data[3] = rpm & 0xff;
error = smu_run_cmd(smu, &cmd, 1);
- if (error)
+ if (error && error != EWOULDBLOCK)
fan->old_style = 1;
}
@@ -704,8 +682,9 @@ smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm)
}
static int
-smu_fan_read_rpm(device_t smu, struct smu_fan *fan)
+smu_fan_read_rpm(struct smu_fan *fan)
{
+ device_t smu = fan->dev;
struct smu_cmd cmd;
int rpm, error;
@@ -716,7 +695,7 @@ smu_fan_read_rpm(device_t smu, struct smu_fan *fan)
cmd.data[1] = fan->reg;
error = smu_run_cmd(smu, &cmd, 1);
- if (error)
+ if (error && error != EWOULDBLOCK)
fan->old_style = 1;
rpm = (cmd.data[0] << 8) | cmd.data[1];
@@ -749,7 +728,7 @@ smu_fanrpm_sysctl(SYSCTL_HANDLER_ARGS)
sc = device_get_softc(smu);
fan = &sc->sc_fans[arg2];
- rpm = smu_fan_read_rpm(smu, fan);
+ rpm = smu_fan_read_rpm(fan);
if (rpm < 0)
return (rpm);
@@ -760,7 +739,7 @@ smu_fanrpm_sysctl(SYSCTL_HANDLER_ARGS)
sc->sc_lastuserchange = time_uptime;
- return (smu_fan_set_rpm(smu, fan, rpm));
+ return (smu_fan_set_rpm(fan, rpm));
}
static void
@@ -801,23 +780,25 @@ smu_attach_fans(device_t dev, phandle_t fanroot)
if (strcmp(type, "fan-rpm-control") != 0)
continue;
+ fan->dev = dev;
fan->old_style = 0;
OF_getprop(child, "reg", &fan->reg, sizeof(cell_t));
- OF_getprop(child, "min-value", &fan->min_rpm, sizeof(cell_t));
- OF_getprop(child, "max-value", &fan->max_rpm, sizeof(cell_t));
+ OF_getprop(child, "min-value", &fan->fan.min_rpm, sizeof(int));
+ OF_getprop(child, "max-value", &fan->fan.max_rpm, sizeof(int));
+ OF_getprop(child, "zone", &fan->fan.zone, sizeof(int));
- if (OF_getprop(child, "unmanaged-value", &fan->unmanaged_rpm,
- sizeof(cell_t)) != sizeof(cell_t))
- fan->unmanaged_rpm = fan->max_rpm;
+ if (OF_getprop(child, "unmanaged-value", &fan->fan.default_rpm,
+ sizeof(int)) != sizeof(int))
+ fan->fan.default_rpm = fan->fan.max_rpm;
- fan->setpoint = smu_fan_read_rpm(dev, fan);
+ fan->setpoint = smu_fan_read_rpm(fan);
- OF_getprop(child, "location", fan->location,
- sizeof(fan->location));
+ OF_getprop(child, "location", fan->fan.name,
+ sizeof(fan->fan.name));
/* Add sysctls */
- for (i = 0; i < strlen(fan->location); i++) {
- sysctl_name[i] = tolower(fan->location[i]);
+ for (i = 0; i < strlen(fan->fan.name); i++) {
+ sysctl_name[i] = tolower(fan->fan.name[i]);
if (isspace(sysctl_name[i]))
sysctl_name[i] = '_';
}
@@ -826,23 +807,28 @@ smu_attach_fans(device_t dev, phandle_t fanroot)
oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(fanroot_oid),
OID_AUTO, sysctl_name, CTLFLAG_RD, 0, "Fan Information");
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "minrpm",
- CTLTYPE_INT | CTLFLAG_RD, &fan->min_rpm, sizeof(cell_t),
+ CTLTYPE_INT | CTLFLAG_RD, &fan->fan.min_rpm, sizeof(int),
"Minimum allowed RPM");
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "maxrpm",
- CTLTYPE_INT | CTLFLAG_RD, &fan->max_rpm, sizeof(cell_t),
+ CTLTYPE_INT | CTLFLAG_RD, &fan->fan.max_rpm, sizeof(int),
"Maximum allowed RPM");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "rpm",
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev,
sc->sc_nfans, smu_fanrpm_sysctl, "I", "Fan RPM");
+ fan->fan.read = (int (*)(struct pmac_fan *))smu_fan_read_rpm;
+ fan->fan.set = (int (*)(struct pmac_fan *, int))smu_fan_set_rpm;
+ pmac_thermal_fan_register(&fan->fan);
+
fan++;
sc->sc_nfans++;
}
}
static int
-smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
+smu_sensor_read(struct smu_sensor *sens)
{
+ device_t smu = sens->dev;
struct smu_cmd cmd;
struct smu_softc *sc;
int64_t value;
@@ -855,7 +841,7 @@ smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
error = smu_run_cmd(smu, &cmd, 1);
if (error != 0)
- return (error);
+ return (-1);
sc = device_get_softc(smu);
value = (cmd.data[0] << 8) | cmd.data[1];
@@ -867,8 +853,8 @@ smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
value += ((int64_t)sc->sc_cpu_diode_offset) << 9;
value <<= 1;
- /* Convert from 16.16 fixed point degC into integer C. */
- value >>= 16;
+ /* Convert from 16.16 fixed point degC into integer 0.1 K. */
+ value = 10*(value >> 16) + 2732;
break;
case SMU_VOLTAGE_SENSOR:
value *= sc->sc_cpu_volt_scale;
@@ -902,8 +888,7 @@ smu_sensor_read(device_t smu, struct smu_sensor *sens, int *val)
break;
}
- *val = value;
- return (0);
+ return (value);
}
static int
@@ -918,9 +903,9 @@ smu_sensor_sysctl(SYSCTL_HANDLER_ARGS)
sc = device_get_softc(smu);
sens = &sc->sc_sensors[arg2];
- error = smu_sensor_read(smu, sens, &value);
- if (error != 0)
- return (error);
+ value = smu_sensor_read(sens);
+ if (value < 0)
+ return (EBUSY);
error = sysctl_handle_int(oidp, &value, 0, req);
@@ -964,6 +949,7 @@ smu_attach_sensors(device_t dev, phandle_t sensroot)
char sysctl_name[40], sysctl_desc[40];
const char *units;
+ sens->dev = dev;
OF_getprop(child, "device_type", type, sizeof(type));
if (strcmp(type, "current-sensor") == 0) {
@@ -983,98 +969,37 @@ smu_attach_sensors(device_t dev, phandle_t sensroot)
}
OF_getprop(child, "reg", &sens->reg, sizeof(cell_t));
- OF_getprop(child, "location", sens->location,
- sizeof(sens->location));
+ OF_getprop(child, "zone", &sens->therm.zone, sizeof(int));
+ OF_getprop(child, "location", sens->therm.name,
+ sizeof(sens->therm.name));
- for (i = 0; i < strlen(sens->location); i++) {
- sysctl_name[i] = tolower(sens->location[i]);
+ for (i = 0; i < strlen(sens->therm.name); i++) {
+ sysctl_name[i] = tolower(sens->therm.name[i]);
if (isspace(sysctl_name[i]))
sysctl_name[i] = '_';
}
sysctl_name[i] = 0;
- sprintf(sysctl_desc,"%s (%s)", sens->location, units);
+ sprintf(sysctl_desc,"%s (%s)", sens->therm.name, units);
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensroot_oid), OID_AUTO,
sysctl_name, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
- dev, sc->sc_nsensors, smu_sensor_sysctl, "I", sysctl_desc);
-
- sens++;
- sc->sc_nsensors++;
- }
-}
-
-static void
-smu_fan_management_proc(void *xdev)
-{
- device_t smu = xdev;
-
- while(1) {
- smu_manage_fans(smu);
- pause("smu", SMU_FANMGT_INTERVAL * hz / 1000);
- }
-}
-
-static void
-smu_manage_fans(device_t smu)
-{
- struct smu_softc *sc;
- int i, maxtemp, temp, factor, error;
-
- sc = device_get_softc(smu);
-
- maxtemp = 0;
- for (i = 0; i < sc->sc_nsensors; i++) {
- if (sc->sc_sensors[i].type != SMU_TEMP_SENSOR)
- continue;
-
- error = smu_sensor_read(smu, &sc->sc_sensors[i], &temp);
- if (error == 0 && temp > maxtemp)
- maxtemp = temp;
- }
+ dev, sc->sc_nsensors, smu_sensor_sysctl,
+ (sens->type == SMU_TEMP_SENSOR) ? "IK" : "I", sysctl_desc);
- if (maxtemp > sc->sc_critical_temp) {
- device_printf(smu, "WARNING: Current system temperature (%d C) "
- "exceeds critical temperature (%d C)! Shutting down!\n",
- maxtemp, sc->sc_critical_temp);
- shutdown_nice(RB_POWEROFF);
- }
-
- if (maxtemp - sc->sc_target_temp > 20)
- device_printf(smu, "WARNING: Current system temperature (%d C) "
- "more than 20 degrees over target temperature (%d C)!\n",
- maxtemp, sc->sc_target_temp);
-
- if (time_uptime - sc->sc_lastuserchange < 3) {
- /*
- * If we have heard from a user process in the last 3 seconds,
- * go away.
- */
+ if (sens->type == SMU_TEMP_SENSOR) {
+ /* Make up some numbers */
+ sens->therm.target_temp = 500 + 2732; /* 50 C */
+ sens->therm.max_temp = 900 + 2732; /* 90 C */
- return;
- }
+ sens->therm.read =
+ (int (*)(struct pmac_therm *))smu_sensor_read;
+ pmac_thermal_sensor_register(&sens->therm);
+ }
- if (maxtemp < 10) { /* Bail if no good sensors */
- for (i = 0; i < sc->sc_nfans; i++)
- smu_fan_set_rpm(smu, &sc->sc_fans[i],
- sc->sc_fans[i].unmanaged_rpm);
- return;
+ sens++;
+ sc->sc_nsensors++;
}
-
- if (maxtemp - sc->sc_target_temp > 4)
- factor = 110;
- else if (maxtemp - sc->sc_target_temp > 1)
- factor = 105;
- else if (sc->sc_target_temp - maxtemp > 4)
- factor = 90;
- else if (sc->sc_target_temp - maxtemp > 1)
- factor = 95;
- else
- factor = 100;
-
- for (i = 0; i < sc->sc_nfans; i++)
- smu_fan_set_rpm(smu, &sc->sc_fans[i],
- (sc->sc_fans[i].setpoint * factor) / 100);
}
static void
diff --git a/sys/powerpc/powermac/smusat.c b/sys/powerpc/powermac/smusat.c
index 42f023a..886cd4f 100644
--- a/sys/powerpc/powermac/smusat.c
+++ b/sys/powerpc/powermac/smusat.c
@@ -43,9 +43,13 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
+#include <powerpc/powermac/powermac_thermal.h>
+
struct smu_sensor {
+ struct pmac_therm therm;
+ device_t dev;
+
cell_t reg;
- char location[32];
enum {
SMU_CURRENT_SENSOR,
SMU_VOLTAGE_SENSOR,
@@ -57,6 +61,7 @@ struct smu_sensor {
static int smusat_probe(device_t);
static int smusat_attach(device_t);
static int smusat_sensor_sysctl(SYSCTL_HANDLER_ARGS);
+static int smusat_sensor_read(struct smu_sensor *sens);
MALLOC_DEFINE(M_SMUSAT, "smusat", "SMU Sattelite Sensors");
@@ -135,14 +140,16 @@ smusat_attach(device_t dev)
char sysctl_name[40], sysctl_desc[40];
const char *units;
+ sens->dev = dev;
sens->reg = 0;
OF_getprop(child, "reg", &sens->reg, sizeof(sens->reg));
if (sens->reg < 0x30)
continue;
-
sens->reg -= 0x30;
- OF_getprop(child, "location", sens->location,
- sizeof(sens->location));
+
+ OF_getprop(child, "zone", &sens->therm.zone, sizeof(int));
+ OF_getprop(child, "location", sens->therm.name,
+ sizeof(sens->therm.name));
OF_getprop(child, "device_type", type, sizeof(type));
@@ -162,17 +169,27 @@ smusat_attach(device_t dev)
continue;
}
- for (i = 0; i < strlen(sens->location); i++) {
- sysctl_name[i] = tolower(sens->location[i]);
+ for (i = 0; i < strlen(sens->therm.name); i++) {
+ sysctl_name[i] = tolower(sens->therm.name[i]);
if (isspace(sysctl_name[i]))
sysctl_name[i] = '_';
}
sysctl_name[i] = 0;
- sprintf(sysctl_desc,"%s (%s)", sens->location, units);
+ sprintf(sysctl_desc,"%s (%s)", sens->therm.name, units);
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensroot_oid), OID_AUTO,
sysctl_name, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev,
- sc->sc_nsensors, smusat_sensor_sysctl, "I", sysctl_desc);
+ sc->sc_nsensors, smusat_sensor_sysctl,
+ (sens->type == SMU_TEMP_SENSOR) ? "IK" : "I", sysctl_desc);
+
+ if (sens->type == SMU_TEMP_SENSOR) {
+ /* Make up some numbers */
+ sens->therm.target_temp = 500 + 2732; /* 50 C */
+ sens->therm.max_temp = 900 + 2732; /* 90 C */
+ sens->therm.read =
+ (int (*)(struct pmac_therm *))smusat_sensor_read;
+ pmac_thermal_sensor_register(&sens->therm);
+ }
sens++;
sc->sc_nsensors++;
@@ -198,11 +215,13 @@ smusat_updatecache(device_t dev)
}
static int
-smusat_sensor_read(device_t dev, struct smu_sensor *sens, int *val)
+smusat_sensor_read(struct smu_sensor *sens)
{
int value;
+ device_t dev;
struct smusat_softc *sc;
+ dev = sens->dev;
sc = device_get_softc(dev);
if (time_uptime - sc->sc_last_update > 1)
@@ -215,8 +234,8 @@ smusat_sensor_read(device_t dev, struct smu_sensor *sens, int *val)
case SMU_TEMP_SENSOR:
/* 16.16 */
value <<= 10;
- /* Kill the .16 */
- value >>= 16;
+ /* From 16.16 to 0.1 C */
+ value = 10*(value >> 16) + 2732;
break;
case SMU_VOLTAGE_SENSOR:
/* 16.16 */
@@ -235,8 +254,7 @@ smusat_sensor_read(device_t dev, struct smu_sensor *sens, int *val)
break;
}
- *val = value;
- return (0);
+ return (value);
}
static int
@@ -251,9 +269,9 @@ smusat_sensor_sysctl(SYSCTL_HANDLER_ARGS)
sc = device_get_softc(dev);
sens = &sc->sc_sensors[arg2];
- error = smusat_sensor_read(dev, sens, &value);
- if (error != 0)
- return (error);
+ value = smusat_sensor_read(sens);
+ if (value < 0)
+ return (EBUSY);
error = sysctl_handle_int(oidp, &value, 0, req);
diff --git a/sys/sys/racct.h b/sys/sys/racct.h
index cbd96a9..222dbce 100644
--- a/sys/sys/racct.h
+++ b/sys/sys/racct.h
@@ -49,27 +49,25 @@ struct ucred;
*/
#define RACCT_UNDEFINED -1
#define RACCT_CPU 0
-#define RACCT_FSIZE 1
-#define RACCT_DATA 2
-#define RACCT_STACK 3
-#define RACCT_CORE 4
-#define RACCT_RSS 5
-#define RACCT_MEMLOCK 6
-#define RACCT_NPROC 7
-#define RACCT_NOFILE 8
-#define RACCT_SBSIZE 9
-#define RACCT_VMEM 10
-#define RACCT_NPTS 11
-#define RACCT_SWAP 12
-#define RACCT_NTHR 13
-#define RACCT_MSGQQUEUED 14
-#define RACCT_MSGQSIZE 15
-#define RACCT_NMSGQ 16
-#define RACCT_NSEM 17
-#define RACCT_NSEMOP 18
-#define RACCT_NSHM 19
-#define RACCT_SHMSIZE 20
-#define RACCT_WALLCLOCK 21
+#define RACCT_DATA 1
+#define RACCT_STACK 2
+#define RACCT_CORE 3
+#define RACCT_RSS 4
+#define RACCT_MEMLOCK 5
+#define RACCT_NPROC 6
+#define RACCT_NOFILE 7
+#define RACCT_VMEM 8
+#define RACCT_NPTS 9
+#define RACCT_SWAP 10
+#define RACCT_NTHR 11
+#define RACCT_MSGQQUEUED 12
+#define RACCT_MSGQSIZE 13
+#define RACCT_NMSGQ 14
+#define RACCT_NSEM 15
+#define RACCT_NSEMOP 16
+#define RACCT_NSHM 17
+#define RACCT_SHMSIZE 18
+#define RACCT_WALLCLOCK 19
#define RACCT_MAX RACCT_WALLCLOCK
/*
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 9b5425b..5b8f3c8 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -1022,7 +1022,7 @@ dup_alloc:
(*vpp)->v_op = &ffs_vnodeops1;
return (0);
noinodes:
- if (fs->fs_pendinginodes > 0 && reclaimed == 0) {
+ if (reclaimed == 0) {
reclaimed = 1;
softdep_request_cleanup(fs, pvp, cred, FLUSH_INODES_WAIT);
goto retry;
OpenPOWER on IntegriCloud