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> |