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

View File

@@ -47,10 +47,14 @@ ASFLAGS ?=
CFLAGS ?= CFLAGS ?=
CFLAGS += $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS) CFLAGS += $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
CFLAGS += -DGIT_VERSION="\"$(VERSION)\"" CFLAGS += -DGIT_VERSION="L\"$(VERSION)\""
CFLAGS += -std=c11 -fno-stack-protector -fpic -fshort-wchar -mno-red-zone CFLAGS += -std=c11 -fno-stack-protector -fpic -fshort-wchar -mno-red-zone
CFLAGS += -DEFI_DEBUG=0 -DEFI_DEBUG_CLEAR_MEMORY=0 -DGNU_EFI_USE_MS_ABI -DHAVE_USE_MS_ABI #-DEFI_FUNCTION_WRAPPER CFLAGS += -DEFI_DEBUG=0 -DEFI_DEBUG_CLEAR_MEMORY=0 -DGNU_EFI_USE_MS_ABI -DHAVE_USE_MS_ABI #-DEFI_FUNCTION_WRAPPER
ifdef MAX_HRES
CFLAGS += -DMAX_HRES=$(MAX_HRES)
endif
LDFLAGS ?= LDFLAGS ?=
LDFLAGS += -L $(BUILD_D) -ggdb LDFLAGS += -L $(BUILD_D) -ggdb
LDFLAGS += -nostdlib -znocombreloc -shared -Bsymbolic -fPIC -nostartfiles LDFLAGS += -nostdlib -znocombreloc -shared -Bsymbolic -fPIC -nostartfiles
@@ -76,7 +80,7 @@ QEMU ?= qemu-system-x86_64
GDBPORT ?= 27006 GDBPORT ?= 27006
CPUS ?= 2 CPUS ?= 2
OVMF ?= assets/ovmf/x64/OVMF.fd OVMF ?= assets/ovmf/x64/OVMF.fd
QEMUOPTS := -bios $(OVMF) -hda $(BUILD_D)/fs.img -smp $(CPUS) -m 512 -nographic $(QEMUEXTRA) QEMUOPTS := -bios $(OVMF) -hda $(BUILD_D)/fs.img -smp $(CPUS) -m 512 $(QEMUEXTRA)
all: $(BUILD_D)/fs.img all: $(BUILD_D)/fs.img
@@ -150,6 +154,9 @@ $(BUILD_D)/fs.iso: $(BUILD_D)/fs.img
xorriso -as mkisofs -R -f -e fs.img -no-emul-boot -o $@ $(BUILD_D)/iso xorriso -as mkisofs -R -f -e fs.img -no-emul-boot -o $@ $(BUILD_D)/iso
qemu: $(BUILD_D)/fs.img qemu: $(BUILD_D)/fs.img
"$(QEMU)" $(QEMUOPTS) -nographic
qemu-window: $(BUILD_D)/fs.img
"$(QEMU)" $(QEMUOPTS) "$(QEMU)" $(QEMUOPTS)
qemu-gdb: $(BUILD_D)/fs.img $(BUILD_D)/kernel.debug.efi qemu-gdb: $(BUILD_D)/fs.img $(BUILD_D)/kernel.debug.efi

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 <efi.h>
#include <efilib.h> #include <efilib.h>
#include "graphics.h" #include "console.h"
#include "utility.h" #include "utility.h"
#ifndef GIT_VERSION
#define GIT_VERSION L"no version"
#endif
EFI_STATUS EFI_STATUS
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) 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); 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); // From here on out, use CHECK_EFI_STATUS_OR_FAIL instead
CHECK_EFI_STATUS_OR_RETURN(status, "set_graphics_mode"); // because the console is now set up
Print(L" SystemTable: %x\n", SystemTable); Print(L" SystemTable: %x\n", SystemTable);
if (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 <efi.h>
#include <efilib.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))) { \ 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); \ 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"); \
}