Moved graphics.c into console.h, with boot message framework

This commit is contained in:
Justin C. Miller
2017-01-16 16:42:11 -08:00
parent 0260abecab
commit 29922e3546
8 changed files with 174 additions and 65 deletions

116
src/arch/x86_64/console.c Normal file
View File

@@ -0,0 +1,116 @@
#include <efi.h>
#include <efilib.h>
#include <stdint.h>
#include "console.h"
#include "utility.h"
UINTN ROWS = 0;
UINTN COLS = 0;
EFI_STATUS
con_initialize (const CHAR16 *version)
{
EFI_STATUS status;
Print(L"Setting console display mode...\n");
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
EFI_GUID gfx_out_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
status = ST->BootServices->LocateProtocol(
&gfx_out_guid, NULL, (void**)&gfx_out_proto);
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
uint32_t res =
gfx_out_proto->Mode->Info->HorizontalResolution *
gfx_out_proto->Mode->Info->VerticalResolution;
uint32_t best = gfx_out_proto->Mode->Mode;
for (uint32_t i = 0; i < modes; ++i) {
UINTN size = 0;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL;
status = gfx_out_proto->QueryMode(gfx_out_proto, i, &size, &info);
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
#ifdef MAX_HRES
if (info->HorizontalResolution > MAX_HRES)
continue;
#endif
const uint32_t new_res =
info->HorizontalResolution *
info->VerticalResolution;
if (new_res > res) {
best = i;
res = new_res;
}
}
status = gfx_out_proto->SetMode(gfx_out_proto, best);
CHECK_EFI_STATUS_OR_RETURN(status, "SetMode %d/%d", best, modes);
status = ST->ConOut->QueryMode(
ST->ConOut,
ST->ConOut->Mode->Mode,
&COLS, &ROWS);
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
status = ST->ConOut->ClearScreen(ST->ConOut);
CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen");
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTCYAN);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"Popcorn OS ");
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTMAGENTA);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)version);
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L" booting...\r\n");
con_status_begin(L"Setting console display mode: ");
Print(L"%ux%u (%ux%u chars)\n",
gfx_out_proto->Mode->Info->HorizontalResolution,
gfx_out_proto->Mode->Info->VerticalResolution,
ROWS, COLS);
con_status_ok();
return status;
}
void
con_status_begin (const CHAR16 *message)
{
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)message);
}
void
con_status_ok ()
{
UINTN row = ST->ConOut->Mode->CursorRow;
ST->ConOut->SetCursorPosition(ST->ConOut, COLS - 8, row - 1);
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"[");
ST->ConOut->SetAttribute(ST->ConOut, EFI_GREEN);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L" ok ");
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"]\r");
}
void
con_status_fail (const CHAR16 *error)
{
UINTN row = ST->ConOut->Mode->CursorRow;
ST->ConOut->SetCursorPosition(ST->ConOut, COLS - 8, row - 1);
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"[");
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"failed");
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)L"]\r\n");
ST->ConOut->SetAttribute(ST->ConOut, EFI_RED);
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)error);
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <efi.h>
EFI_STATUS con_initialize (const CHAR16 *version);
void con_status_begin (const CHAR16 *message);
void con_status_ok ();
void con_status_fail (const CHAR16 *error);

View File

@@ -1,53 +0,0 @@
#include <efi.h>
#include <efilib.h>
#include "utility.h"
EFI_STATUS
set_graphics_mode (EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS status;
Print(L"Setting console display mode... ");
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
EFI_GUID gfx_out_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
status = SystemTable->BootServices->LocateProtocol(
&gfx_out_guid, NULL, (void**)&gfx_out_proto);
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
uint32_t res =
gfx_out_proto->Mode->Info->HorizontalResolution *
gfx_out_proto->Mode->Info->VerticalResolution;
uint32_t best = (uint32_t)-1;
for (uint32_t i = 0; i < modes; ++i) {
UINTN size = 0;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL;
status = gfx_out_proto->QueryMode(gfx_out_proto, i, &size, &info);
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
const uint32_t new_res =
info->HorizontalResolution *
info->VerticalResolution;
if (new_res > res) {
best = i;
res = new_res;
}
}
if (best != (uint32_t)-1) {
status = gfx_out_proto->SetMode(gfx_out_proto, best);
CHECK_EFI_STATUS_OR_RETURN(status, "SetMode");
Print(L"*");
}
Print(L"%ux%u\n",
gfx_out_proto->Mode->Info->HorizontalResolution,
gfx_out_proto->Mode->Info->VerticalResolution);
return status;
}

View File

@@ -1,4 +0,0 @@
#pragma once
#include <efi.h>
EFI_STATUS set_graphics_mode (EFI_SYSTEM_TABLE *SystemTable);

View File

@@ -1,9 +1,13 @@
#include <efi.h>
#include <efilib.h>
#include "graphics.h"
#include "console.h"
#include "utility.h"
#ifndef GIT_VERSION
#define GIT_VERSION L"no version"
#endif
EFI_STATUS
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
@@ -11,10 +15,14 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
InitializeLib(ImageHandle, SystemTable);
Print(L"Popcorn OS " GIT_VERSION L" booting...\n");
// When checking the console initialization error,
// use CHECK_EFI_STATUS_OR_RETURN because we can't
// be sure if the console was fully set up
status = con_initialize(GIT_VERSION);
CHECK_EFI_STATUS_OR_RETURN(status, "con_initialize");
status = set_graphics_mode(SystemTable);
CHECK_EFI_STATUS_OR_RETURN(status, "set_graphics_mode");
// From here on out, use CHECK_EFI_STATUS_OR_FAIL instead
// because the console is now set up
Print(L" SystemTable: %x\n", SystemTable);
if (SystemTable)

18
src/arch/x86_64/utility.c Normal file
View File

@@ -0,0 +1,18 @@
#include <efi.h>
struct ErrorCode {
EFI_STATUS code;
const CHAR16 *desc;
};
extern struct ErrorCode ErrorCodeTable[];
const CHAR16 *util_error_message(EFI_STATUS status) {
int32_t i = -1;
while (ErrorCodeTable[++i].desc != NULL) {
if (ErrorCodeTable[i].code == status)
return ErrorCodeTable[i].desc;
}
return L"Unknown";
}

View File

@@ -1,9 +1,19 @@
#include <efi.h>
#include <efilib.h>
#include "console.h"
#define CHECK_EFI_STATUS_OR_RETURN(s, msg) \
const CHAR16 *util_error_message(EFI_STATUS status);
#define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \
if (EFI_ERROR((s))) { \
Print(L"EFI_ERROR: " msg L" %d\n", (s)); \
Print(L"EFI_ERROR: " msg L": %s\n", ## __VA_ARGS__, util_error_message(s)); \
return (s); \
}
#define CHECK_EFI_STATUS_OR_FAIL(s, msg, ...) \
if (EFI_ERROR((s))) { \
con_status_fail(util_error_message(s)); \
Print(L"\n" msg, ## __VA_ARGS__ ); \
while (1) __asm__("hlt"); \
}