Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135816144
D42695.id131172.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D42695.id131172.diff
View Options
diff --git a/stand/liblua/lutils.c b/stand/liblua/lutils.c
--- a/stand/liblua/lutils.c
+++ b/stand/liblua/lutils.c
@@ -75,6 +75,25 @@
return 1;
}
+static int
+lua_has_feature(lua_State *L)
+{
+ const char *feature;
+ char *msg;
+
+ feature = luaL_checkstring(L, 1);
+
+ if (feature_name_is_enabled(feature)) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+
+ lua_pushnil(L);
+ lua_pushstring(L, "Feature not enabled");
+ return 2;
+}
+
+
static int
lua_perform(lua_State *L)
{
@@ -552,6 +571,7 @@
REG_SIMPLE(parse),
REG_SIMPLE(getenv),
REG_SIMPLE(has_command),
+ REG_SIMPLE(has_feature),
REG_SIMPLE(perform),
REG_SIMPLE(printc), /* Also registered as the global 'printc' */
REG_SIMPLE(setenv),
@@ -579,6 +599,33 @@
};
#undef REG_SIMPLE
+static void
+lua_add_feature(void *cookie, const char *name, const char *desc, bool enabled)
+{
+ lua_State *L = cookie;
+
+ /*
+ * The feature table consists solely of features that are enabled, and
+ * their associated descriptions for debugging purposes.
+ */
+ lua_pushstring(L, desc);
+ lua_setfield(L, -2, name);
+}
+
+static void
+lua_add_features(lua_State *L)
+{
+
+ lua_newtable(L);
+ feature_iter(&lua_add_feature, L);
+
+ /*
+ * We should still have just the table on the stack after we're done
+ * iterating.
+ */
+ lua_setfield(L, -2, "features");
+}
+
int
luaopen_loader(lua_State *L)
{
@@ -592,6 +639,7 @@
lua_setfield(L, -2, "lua_path");
lua_pushinteger(L, bootprog_rev);
lua_setfield(L, -2, "version");
+ lua_add_features(L);
/* Set global printc to loader.printc */
lua_register(L, "printc", lua_printc);
return 1;
diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile
--- a/stand/libsa/Makefile
+++ b/stand/libsa/Makefile
@@ -13,7 +13,7 @@
# standalone components and stuff we have modified locally
SRCS+= gzguts.h zutil.h __main.c abort.c assert.c bcd.c environment.c \
- getopt.c gets.c globals.c \
+ features.c getopt.c gets.c globals.c \
hexdump.c nvstore.c pager.c panic.c printf.c strdup.c strerror.c \
random.c sbrk.c tslog.c twiddle.c zalloc.c zalloc_malloc.c
diff --git a/stand/libsa/features.c b/stand/libsa/features.c
new file mode 100644
--- /dev/null
+++ b/stand/libsa/features.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2023 Kyle Evans <kevans@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ */
+
+#include <sys/param.h>
+
+#include "stand.h"
+
+static uint32_t loader_features;
+
+#define FEATURE_ENTRY(name, desc) { FEATURE_##name, #name, desc }
+static const struct feature_entry {
+ uint32_t value;
+ const char *name;
+ const char *desc;
+} feature_map[] = {
+ FEATURE_ENTRY(EARLY_ACPI, "Loader probes ACPI in early startup"),
+};
+
+void
+feature_enable(uint32_t mask)
+{
+
+ loader_features |= mask;
+}
+
+bool
+feature_name_is_enabled(const char *name)
+{
+ const struct feature_entry *entry;
+
+ for (size_t i = 0; i < nitems(feature_map); i++) {
+ entry = &feature_map[i];
+
+ if (strcmp(entry->name, name) == 0)
+ return ((loader_features & entry->value) != 0);
+ }
+
+ return (false);
+}
+
+void
+feature_iter(feature_iter_fn *iter_fn, void *cookie)
+{
+ const struct feature_entry *entry;
+
+ for (size_t i = 0; i < nitems(feature_map); i++) {
+ entry = &feature_map[i];
+
+ (*iter_fn)(cookie, entry->name, entry->desc,
+ (loader_features & entry->value) != 0);
+ }
+}
diff --git a/stand/libsa/libsa.3 b/stand/libsa/libsa.3
--- a/stand/libsa/libsa.3
+++ b/stand/libsa/libsa.3
@@ -497,6 +497,66 @@
.Fa fname .
Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading.
.El
+.Sh FEATURE SUPPORT
+A set of functions are provided to communicate support of features from the
+loader binary to the interpreter.
+These are used to do something sensible if we are still operating with a loader
+binary that behaves differently than expected.
+.Bl -hang -width 10n
+.It Xo
+.Ft void
+.Fn feature_enable "uint32_t mask"
+.Xc
+.Pp
+Enable the referenced
+.Fa mask
+feature, which should be one of the
+.Li FEATURE_*
+macros defined in
+.In stand.h .
+.It Xo
+.Ft bool
+.Fn feature_name_is_enabled "const char *name"
+.Xc
+.Pp
+Check if the referenced
+.Fa name
+feature is enabled.
+The
+.Fa name
+is usually the same name as the
+.Li FEATURE_*
+macro, but with the FEATURE_ prefix stripped off.
+The authoritative source of feature names is the mapping table near the top in
+.Pa stand/libsa/features.c .
+.It Xo
+.Ft void
+.Fn "(feature_iter_fn)" "void *cookie" "const char *name" "const char *desc" "bool enabled"
+.Xc
+.Pp
+The
+.Fa cookie
+argument is passed as-is from the argument of the same name to
+.Fn feature_iter .
+The
+.Fa name
+and
+.Fa desc
+arguments are defined in the mapping table in
+.Pa stand/libsa/features.c .
+The
+.Fa enabled
+argument indicates the current status of the feature, though one could
+theoretically turn a feature off in later execution.
+As such, this should likely not be trusted if it is needed after the iteration
+has finished.
+.It Xo
+.Ft void
+.Fn "feature_iter" "feature_iter_fn *iter_fn" "void *cookie"
+.Xc
+.Pp
+Iterate over the current set of features.
+.El
.Sh MISC
.Bl -hang -width 10n
.It Xo
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -496,6 +496,21 @@
*/
caddr_t ptov(uintptr_t);
+/* features.c */
+typedef void (feature_iter_fn)(void *, const char *, const char *, bool);
+
+extern void feature_enable(uint32_t);
+extern bool feature_name_is_enabled(const char *);
+extern void feature_iter(feature_iter_fn *, void *);
+
+/*
+ * Note that these should also be added to the mapping table in features.c,
+ * which the interpreter may query to provide details from. The name with
+ * FEATURE_ removed is assumed to be the name we'll provide in the loader
+ * features table, just to simplify reasoning about these.
+ */
+#define FEATURE_EARLY_ACPI 0x0001
+
/* hexdump.c */
void hexdump(caddr_t region, size_t len);
diff --git a/stand/lua/core.lua b/stand/lua/core.lua
--- a/stand/lua/core.lua
+++ b/stand/lua/core.lua
@@ -378,6 +378,15 @@
loader.perform(composeLoaderCmd("boot", argstr))
end
+function core.hasFeature(name)
+ if not loader.has_feature then
+ -- Loader too old, no feature support
+ return nil, "No feature support in loaded loader"
+ end
+
+ return loader.has_feature(name)
+end
+
function core.isSingleUserBoot()
local single_user = loader.getenv("boot_single")
return single_user ~= nil and single_user:lower() == "yes"
diff --git a/stand/lua/core.lua.8 b/stand/lua/core.lua.8
--- a/stand/lua/core.lua.8
+++ b/stand/lua/core.lua.8
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 20, 2023
+.Dd December 8, 2023
.Dt CORE.LUA 8
.Os
.Sh NAME
@@ -142,6 +142,13 @@
.Ic kernel
or
.Ic kernels .
+.It Fn core.hasFeature featureName
+Checks whether the named
+.Fa featureName
+is enabled in the current loader.
+This is specifically used for detecting capabilities of the loaded loader
+binary, so that one can reasonably implement backwards compatibility shims if
+needed.
.It Fn core.kernelList
Returns a table of kernels to display on the boot menu.
This will combine
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 14, 4:04 AM (3 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25276073
Default Alt Text
D42695.id131172.diff (7 KB)
Attached To
Mode
D42695: loader: provide a features table for binary compatibilty advertisement
Attached
Detach File
Event Timeline
Log In to Comment