From 5c682c4209deb235a82ef505a8bbca30ea6884f8 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Sun, 20 Apr 2025 19:17:03 +0200 Subject: [PATCH] Get Framebuffer and its modes --- boot/common/init.c | 8 +--- boot/common/ui/ui.c | 38 ++++++++++++---- boot/include/ui/framebuffer.h | 22 +++++++++ boot/include/ui/ui.h | 6 +++ boot/platform/uefi/ui/framebuffer.c | 69 +++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 boot/include/ui/framebuffer.h create mode 100644 boot/include/ui/ui.h create mode 100644 boot/platform/uefi/ui/framebuffer.c diff --git a/boot/common/init.c b/boot/common/init.c index 6ef4552..aad8c4a 100644 --- a/boot/common/init.c +++ b/boot/common/init.c @@ -18,9 +18,7 @@ /*********************************************************************************/ #include -#include -#include -#include +#include #include void axboot_init() @@ -31,7 +29,5 @@ void axboot_init() while (1); } - aurix_load("\\System\\axkrnl"); - - while (1); + ui_init(); } \ No newline at end of file diff --git a/boot/common/ui/ui.c b/boot/common/ui/ui.c index 1894f8d..51ba31e 100644 --- a/boot/common/ui/ui.c +++ b/boot/common/ui/ui.c @@ -17,18 +17,40 @@ /* SOFTWARE. */ /*********************************************************************************/ +#include +#include #include -enum framebuffer_type { - FB_ARGB = 0, - FB_RGBA = 1, -}; - struct ui_config { - uintptr_t framebuffer; - int framebuffer_type; + uintptr_t fb_addr; + struct fb_mode *fb_modes; + int total_modes; + int current_mode; }; -void init_ui() +struct ui_config config; + +void ui_init() { + struct fb_mode *available_fb_modes = NULL; + int total_modes = 0; + int current_mode = 0; + + if (!get_framebuffer(&config.fb_addr, &config.fb_modes, &config.total_modes, &config.current_mode)) { + debug("Failed to acquire a framebuffer!\n"); + while (1); + } + + debug("Dumping framebuffer information\n"); + debug("--------------------------------\n"); + debug("Address: 0x%llx\n", config.fb_addr); + + for (int i = 0; i < config.total_modes; i++) { + debug("\nMode %u:%s\n", i, (i == config.current_mode) ? " (current)" : ""); + debug("Resolution: %ux%u\n", config.fb_modes[i].width, config.fb_modes[i].height); + debug("Bits Per Pixel: %u\n", config.fb_modes[i].bpp); + debug("Pitch: %u\n", config.fb_modes[i].pitch); + } + + while(1); } \ No newline at end of file diff --git a/boot/include/ui/framebuffer.h b/boot/include/ui/framebuffer.h new file mode 100644 index 0000000..523e6ab --- /dev/null +++ b/boot/include/ui/framebuffer.h @@ -0,0 +1,22 @@ +#ifndef _UI_FRAMEBUFFER_H +#define _UI_FRAMEBUFFER_H + +#include +#include + +enum fb_format { + FB_RGBA, + FB_BGRA +}; + +struct fb_mode { + uint32_t width; + uint32_t height; + uint8_t bpp; + uint32_t pitch; + int format; +}; + +bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index); + +#endif /* _UI_FRAMEBUFFER_H */ \ No newline at end of file diff --git a/boot/include/ui/ui.h b/boot/include/ui/ui.h new file mode 100644 index 0000000..d735523 --- /dev/null +++ b/boot/include/ui/ui.h @@ -0,0 +1,6 @@ +#ifndef _UI_UI_H +#define _UI_UI_H + +void ui_init(); + +#endif /* _UI_UI_H */ \ No newline at end of file diff --git a/boot/platform/uefi/ui/framebuffer.c b/boot/platform/uefi/ui/framebuffer.c new file mode 100644 index 0000000..ceb1c16 --- /dev/null +++ b/boot/platform/uefi/ui/framebuffer.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +#include +#include + +bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index) +{ + EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info = NULL; + EFI_UINTN mode_info_size = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + EFI_UINTN SizeOfInfo, numModes, nativeMode; + EFI_UINTN mode_index = 0; + EFI_STATUS Status; + + Status = gBootServices->LocateProtocol(&gop_guid, NULL, (void**)&gop); + if (EFI_ERROR(Status)) { + debug("get_framebuffer(): Unable to locate GOP: %s (0x%llx)\n", efi_status_to_str(Status), Status); + } + + Status = gop->QueryMode(gop, gop->Mode == NULL ? 0 : gop->Mode->Mode, &SizeOfInfo, &mode_info); + // this is needed to get the current video mode + if (Status == EFI_NOT_STARTED) { + Status = gop->SetMode(gop, 0); + } + + if (EFI_ERROR(Status)) { + debug("Unable to get native mode\n"); + } else { + nativeMode = gop->Mode->Mode; + numModes = gop->Mode->MaxMode; + } + + *total_modes = numModes; + *available_modes = (struct fb_mode *)mem_alloc(sizeof(struct fb_mode) * numModes); + + *fb_addr = gop->Mode->FrameBufferBase; + + // get all available modes + for (int i = 0; i < numModes; i++) { + Status = gop->QueryMode(gop, i, &SizeOfInfo, &mode_info); + + (*available_modes)[i].width = mode_info->HorizontalResolution; + (*available_modes)[i].height = mode_info->VerticalResolution; + (*available_modes)[i].bpp = 4; + (*available_modes)[i].pitch = mode_info->PixelsPerScanLine * 4; + + if (mode_info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) { + (*available_modes)[i].format = FB_RGBA; + } else if (mode_info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + (*available_modes)[i].format = FB_BGRA; + } else { + debug("get_framebuffer(): Unknown framebuffer format, assuming BGRA...\n"); + (*available_modes)[i].format = FB_BGRA; + } + + if (i == nativeMode) { + *current_mode_index = i; + } + } + + gop->QueryMode(gop, mode_index, &mode_info_size, &mode_info); + + return true; +} \ No newline at end of file