svn commit: r331464 - in head/stand: defaults efi/loader
Kyle Evans
kevans at FreeBSD.org
Fri Mar 23 21:02:47 UTC 2018
Author: kevans
Date: Fri Mar 23 21:02:46 2018
New Revision: 331464
URL: https://svnweb.freebsd.org/changeset/base/331464
Log:
efi loader: Respect efi_max_resolution in loader.conf(5)
Default the max resolution to 1080p, we'll accept Width x Height
specifications along with the following presets:
- 480p
- 720p
- 1080p
- 2160p or 4k
- 5k
PR: 224825
Differential Revision: https://reviews.freebsd.org/D14801
Modified:
head/stand/defaults/loader.conf
head/stand/efi/loader/framebuffer.c
Modified: head/stand/defaults/loader.conf
==============================================================================
--- head/stand/defaults/loader.conf Fri Mar 23 20:56:18 2018 (r331463)
+++ head/stand/defaults/loader.conf Fri Mar 23 21:02:46 2018 (r331464)
@@ -75,6 +75,9 @@ acpi_video_load="NO" # Load the ACPI video extension
#geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root
bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments
#beastie_disable="NO" # Turn the beastie boot menu on and off
+efi_max_resolution="1080p" # Set the max resolution for EFI loader to use:
+ # 480p, 720p, 1080p, 2160p/4k, 5k, or specify
+ # WidthxHeight (e.g. 1920x1080)
#kernels="kernel kernel.old" # Kernels to display in the boot menu
#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none
#comconsole_speed="9600" # Set the current serial console speed
Modified: head/stand/efi/loader/framebuffer.c
==============================================================================
--- head/stand/efi/loader/framebuffer.c Fri Mar 23 20:56:18 2018 (r331463)
+++ head/stand/efi/loader/framebuffer.c Fri Mar 23 21:02:46 2018 (r331464)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <bootstrap.h>
#include <sys/endian.h>
+#include <sys/param.h>
#include <stand.h>
#include <efi.h>
@@ -45,6 +46,40 @@ static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCO
static EFI_GUID pciio_guid = EFI_PCI_IO_PROTOCOL_GUID;
static EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID;
+static struct named_resolution {
+ const char *name;
+ const char *alias;
+ unsigned int width;
+ unsigned int height;
+} resolutions[] = {
+ {
+ .name = "480p",
+ .width = 640,
+ .height = 480,
+ },
+ {
+ .name = "720p",
+ .width = 1280,
+ .height = 720,
+ },
+ {
+ .name = "1080p",
+ .width = 1920,
+ .height = 1080,
+ },
+ {
+ .name = "2160p",
+ .alias = "4k",
+ .width = 3840,
+ .height = 2160,
+ },
+ {
+ .name = "5k",
+ .width = 5120,
+ .height = 2880,
+ }
+};
+
static u_int
efifb_color_depth(struct efi_fb *efifb)
{
@@ -462,6 +497,57 @@ print_efifb(int mode, struct efi_fb *efifb, int verbos
}
}
+static bool
+efi_resolution_compare(struct named_resolution *res, const char *cmp)
+{
+
+ if (strcasecmp(res->name, cmp) == 0)
+ return (true);
+ if (res->alias != NULL && strcasecmp(res->alias, cmp) == 0)
+ return (true);
+ return (false);
+}
+
+
+static void
+efi_get_max_resolution(int *width, int *height)
+{
+ struct named_resolution *res;
+ char *maxres;
+ char *height_start, *width_start;
+ int idx;
+
+ *width = *height = 0;
+ maxres = getenv("efi_max_resolution");
+ /* No max_resolution set? Bail out; choose highest resolution */
+ if (maxres == NULL)
+ return;
+ /* See if it matches one of our known resolutions */
+ for (idx = 0; idx < nitems(resolutions); ++idx) {
+ res = &resolutions[idx];
+ if (efi_resolution_compare(res, maxres)) {
+ *width = res->width;
+ *height = res->height;
+ return;
+ }
+ }
+ /* Not a known resolution, try to parse it; make a copy we can modify */
+ maxres = strdup(maxres);
+ if (maxres == NULL)
+ return;
+ height_start = strchr(maxres, 'x');
+ if (height_start == NULL) {
+ free(maxres);
+ return;
+ }
+ width_start = maxres;
+ *height_start++ = 0;
+ /* Errors from this will effectively mean "no max" */
+ *width = (int)strtol(width_start, NULL, 0);
+ *height = (int)strtol(height_start, NULL, 0);
+ free(maxres);
+}
+
static int
gop_autoresize(EFI_GRAPHICS_OUTPUT *gop)
{
@@ -470,16 +556,22 @@ gop_autoresize(EFI_GRAPHICS_OUTPUT *gop)
EFI_STATUS status;
UINTN infosz;
UINT32 best_mode, currdim, maxdim, mode;
+ int height, max_height, max_width, width;
best_mode = maxdim = 0;
+ efi_get_max_resolution(&max_width, &max_height);
for (mode = 0; mode < gop->Mode->MaxMode; mode++) {
status = gop->QueryMode(gop, mode, &infosz, &info);
if (EFI_ERROR(status))
continue;
efifb_from_gop(&efifb, gop->Mode, info);
- currdim = info->HorizontalResolution * info->VerticalResolution;
- /* XXX TODO: Allow tunable or something for max resolution */
+ width = info->HorizontalResolution;
+ height = info->VerticalResolution;
+ currdim = width * height;
if (currdim > maxdim) {
+ if ((max_width != 0 && width > max_width) ||
+ (max_height != 0 && height > max_height))
+ continue;
maxdim = currdim;
best_mode = mode;
}
More information about the svn-src-all
mailing list