Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 2 | pmbaty | 1 | This patch makes the currently initialized graphics framebuffer parameters (address, width, height, pixel format) available |
| 2 | to user-space QNX8 programs through the _CS_GRAPHICS configuration strings when booting a x86-compatible BSP from UEFI. |
||
| 3 | |||
| 4 | In <BSP-x86>/src/hardware/startup/boards/x86/main.c |
||
| 5 | |||
| 6 | Just before the call to: |
||
| 7 | |||
| 8 | // Collect information on all free RAM in the system with |
||
| 9 | // the EFI service routine GetMemoryMap |
||
| 10 | init_raminfo_uefi(); |
||
| 11 | |||
| 12 | Insert this self-contained code: |
||
| 13 | |||
| 14 | { // inject information about the current linear framebuffer used by the UEFI setup program -- BEGIN |
||
| 15 | typedef struct efi_gop_mode_info_s { |
||
| 16 | uint32_t version; // version of this data structure. Typically zero for the current UEFI standard revision. |
||
| 17 | uint32_t horizontal_res; // size of the video screen in pixels in the X dimension |
||
| 18 | uint32_t vertical_res; // size of the video screen in pixels in the Y dimension |
||
| 19 | int pixel_format; // physical format of the pixel (0 = RGBx 8-bit, 1 = BGRx 8-bit, 2 = bitmask, 3 = no framebuffer for this mode) |
||
| 20 | struct { |
||
| 21 | uint32_t red_mask; // a bit being set means this bit is used for the red color |
||
| 22 | uint32_t green_mask; // a bit being set means this bit is used for the green color |
||
| 23 | uint32_t blue_mask; // a bit being set means this bit is used for the blue color |
||
| 24 | uint32_t reserved_mask; // a bit being set means this bit is not used by any of the red, green and blue colors |
||
| 25 | } pixel_info; // only valid if pixel_format is 2 (bitmask) |
||
| 26 | uint32_t pixels_per_scanline; // defines the number of pixel elements per video memory line |
||
| 27 | } efi_gop_mode_info_t; |
||
| 28 | typedef struct efi_gop_mode_s { |
||
| 29 | uint32_t max_mode; // number of modes supported by QueryMode() and SetMode() |
||
| 30 | uint32_t current_mode; // current Mode of the graphics device (0 to max_mode-1) |
||
| 31 | efi_gop_mode_info_t *info; // pointer to read-only efi_gop_mode_info_t data |
||
| 32 | _Uintn info_size; // size of info structure in bytes |
||
| 33 | uint64_t framebuffer_base; // base address of graphics linear frame buffer, where offset zero represents the upper left pixel of the display |
||
| 34 | _Uintn framebuffer_size; // amount of frame buffer needed to support the active mode as defined by PixelsPerScanLine x VerticalResolution x PixelElementSize |
||
| 35 | } efi_gop_mode_t; |
||
| 36 | typedef struct efi_gop_s { |
||
| 37 | EFI_STATUS (*QueryMode) (void *this_gop, uint32_t mode_number, _Uintn *info_size, efi_gop_mode_info_t **info); |
||
| 38 | EFI_STATUS (*SetMode) (void *this_gop, uint32_t mode_number); |
||
| 39 | EFI_STATUS (*Blt) (void *this_gop, void *blit_buffer, int blit_op, _Uintn src_x, _Uintn src_y, _Uintn dst_x, _Uintn dst_y, _Uintn w, _Uintn h, _Uintn delta); |
||
| 40 | efi_gop_mode_t *mode; // pointer to efi_gop_mode_t data |
||
| 41 | } efi_gop_t; |
||
| 42 | efi_gop_t *gop = NULL; |
||
| 43 | EFI_GUID gop_guid = { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } }; // EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID |
||
| 44 | if (efi_system_table->BootServices->LocateProtocol (&gop_guid, NULL, (void **) &gop) == 0) // obtain a pointer to the UEFI GOP API |
||
| 45 | { |
||
| 46 | _Uintn info_size; |
||
| 47 | efi_gop_mode_info_t *info; |
||
| 48 | EFI_STATUS status = gop->QueryMode (gop, (gop->mode == NULL ? 0 : gop->mode->current_mode), &info_size, &info); // obtain information about the current graphic mode |
||
| 49 | if (status == EFI_NOT_STARTED) // graphic output not started yet ? |
||
| 50 | { |
||
| 51 | gop->SetMode (gop, 0); // initialize display with the first available mode if the UEFI program didn't do it already |
||
| 52 | status = gop->QueryMode (gop, (gop->mode == NULL ? 0 : gop->mode->current_mode), &info_size, &info); // obtain information about the current graphic mode again |
||
| 53 | } |
||
| 54 | if ((status == 0) && (gop->mode != NULL) && (gop->mode->info != NULL) && (gop->mode->info->version == 0) && (gop->mode->info->pixel_format < 3)) // valid graphic mode info obtained ? |
||
| 55 | { |
||
| 56 | static char framebuffer_confstr[64] = ""; // keep allocations on the heap |
||
| 57 | char *pixfmt_string = "none"; |
||
| 58 | if (gop->mode->info->pixel_format == 0) pixfmt_string = "RGBx"; // only support 32-bit modes at the moment |
||
| 59 | else if (gop->mode->info->pixel_format == 1) pixfmt_string = "BGRx"; // only support 32-bit modes at the moment |
||
| 60 | ksprintf (framebuffer_confstr, "0x%L %d %d %d %s", gop->mode->framebuffer_base, gop->mode->framebuffer_size, gop->mode->info->horizontal_res, gop->mode->info->vertical_res, pixfmt_string); |
||
| 61 | add_typed_string (_CS_GRAPHICS, framebuffer_confstr); // save this configuration in the _CS_GRAPHICS configuration string |
||
| 62 | kprintf ("framebuffer at 0x%L size %d res %dx%d format %s\n", gop->mode->framebuffer_base, gop->mode->framebuffer_size, gop->mode->info->horizontal_res, gop->mode->info->vertical_res, pixfmt_string); |
||
| 63 | } |
||
| 64 | else |
||
| 65 | { |
||
| 66 | static const char uefi_lfb_error2[] = "unable to get linear framebuffer default graphic mode information from EFI\n"; |
||
| 67 | kprintf (uefi_lfb_error2); // print error on kernel standard error |
||
| 68 | uefi_print_str ((char *) uefi_lfb_error2); // and also on the EFI console |
||
| 69 | } |
||
| 70 | } |
||
| 71 | else |
||
| 72 | { |
||
| 73 | static const char uefi_lfb_error1[] = "unable to locate UEFI Graphic Output Protocol (no display?)\n"; |
||
| 74 | kprintf (uefi_lfb_error1); // print error on kernel standard error |
||
| 75 | uefi_print_str ((char *) uefi_lfb_error1); // and also on the EFI console |
||
| 76 | } |
||
| 77 | } // inject information about the current linear framebuffer used by the UEFI setup program -- END |
||
| 78 | |||
| 79 | Rebuild your BSP and use the _CS_GRAPHICS value from user-space to fire up a working UEFI console driver. |
||
| 80 | |||
| 81 | -- |
||
| 82 | Pierre-Marie Baty <pm@pmbaty.com> |