Changeset View
Changeset View
Standalone View
Standalone View
stand/efi/loader/framebuffer.c
Show First 20 Lines • Show All 419 Lines • ▼ Show 20 Lines | efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga) | ||||
/* | /* | ||||
* We finalized on the stride, so recalculate the size of the | * We finalized on the stride, so recalculate the size of the | ||||
* frame buffer. | * frame buffer. | ||||
*/ | */ | ||||
efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4; | efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | |||||
efi_gop_best_mode(EFI_GRAPHICS_OUTPUT *gop) | |||||
{ | |||||
struct efi_fb efifb; | |||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; | |||||
EFI_STATUS status; | |||||
UINTN infosz; | |||||
UINT32 best_mode, currdim, maxdim, mode; | |||||
best_mode = maxdim = 0; | |||||
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; | |||||
if (currdim > maxdim) { | |||||
imp: There are complaints about it always picking the highest pixel count, since some are large and… | |||||
maxdim = currdim; | |||||
best_mode = mode; | |||||
} | |||||
} | |||||
return (best_mode); | |||||
} | |||||
static int | |||||
efi_reset_gop(void) | |||||
{ | |||||
EFI_GRAPHICS_OUTPUT *gop; | |||||
EFI_STATUS status; | |||||
UINT32 best_mode; | |||||
status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop); | |||||
if (EFI_ERROR(status)) | |||||
return (1); | |||||
/* | |||||
* We try to set the largest supported mode we can find. Depending on | |||||
* how our console is setup, this will either match or be larger than | |||||
* the current screen geometry, yielding a successful reset and putting | |||||
* us into a consistent state before we exit the loader. | |||||
*/ | |||||
best_mode = efi_gop_best_mode(gop); | |||||
status = gop->SetMode(gop, best_mode); | |||||
return (EFI_ERROR(status)); | |||||
} | |||||
static int | |||||
efi_reset_uga(void) | |||||
{ | |||||
return (0); | |||||
} | |||||
int | int | ||||
efi_find_framebuffer(struct efi_fb *efifb) | efi_reset_framebuffer() | ||||
{ | { | ||||
struct efi_fb efifb; | |||||
efi_fb_providers provider; | |||||
if (efi_find_framebuffer(&efifb, &provider) != 0) | |||||
return (1); | |||||
switch (provider) { | |||||
case PROVIDER_GOP: | |||||
return (efi_reset_gop()); | |||||
case PROVIDER_UGA: | |||||
return (efi_reset_uga()); | |||||
default: | |||||
return (1); | |||||
} | |||||
} | |||||
int | |||||
efi_find_framebuffer(struct efi_fb *efifb, efi_fb_providers *provider) | |||||
{ | |||||
EFI_GRAPHICS_OUTPUT *gop; | EFI_GRAPHICS_OUTPUT *gop; | ||||
EFI_UGA_DRAW_PROTOCOL *uga; | EFI_UGA_DRAW_PROTOCOL *uga; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop); | status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop); | ||||
if (status == EFI_SUCCESS) | if (status == EFI_SUCCESS) { | ||||
if (provider != NULL) | |||||
*provider = PROVIDER_GOP; | |||||
return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); | return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); | ||||
} | |||||
status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga); | status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga); | ||||
if (status == EFI_SUCCESS) | if (status == EFI_SUCCESS) { | ||||
if (provider != NULL) | |||||
*provider = PROVIDER_UGA; | |||||
return (efifb_from_uga(efifb, uga)); | return (efifb_from_uga(efifb, uga)); | ||||
} | |||||
return (1); | return (1); | ||||
} | } | ||||
static void | static void | ||||
print_efifb(int mode, struct efi_fb *efifb, int verbose) | print_efifb(int mode, struct efi_fb *efifb, int verbose) | ||||
{ | { | ||||
u_int depth; | u_int depth; | ||||
▲ Show 20 Lines • Show All 119 Lines • Show Last 20 Lines |
There are complaints about it always picking the highest pixel count, since some are large and the font is tiny on them.