Subversion Repositories QNX 8.QNX8 utilities

Rev

Blame | Last modification | View Log | Download | RSS feed

This patch makes the currently initialized graphics framebuffer parameters (address, width, height, pixel format) available
to user-space QNX8 programs through the _CS_GRAPHICS configuration strings when booting a x86-compatible BSP from UEFI.

In <BSP-x86>/src/hardware/startup/boards/x86/main.c

Just before the call to:

                // Collect information on all free RAM in the system with
                // the EFI service routine GetMemoryMap
                init_raminfo_uefi();

Insert this self-contained code:

                { // inject information about the current linear framebuffer used by the UEFI setup program -- BEGIN
                        typedef struct efi_gop_mode_info_s {
                                uint32_t version; // version of this data structure. Typically zero for the current UEFI standard revision.
                                uint32_t horizontal_res; // size of the video screen in pixels in the X dimension
                                uint32_t vertical_res; // size of the video screen in pixels in the Y dimension
                                int pixel_format; // physical format of the pixel (0 = RGBx 8-bit, 1 = BGRx 8-bit, 2 = bitmask, 3 = no framebuffer for this mode)
                                struct {
                                        uint32_t red_mask; // a bit being set means this bit is used for the red color
                                        uint32_t green_mask; // a bit being set means this bit is used for the green color
                                        uint32_t blue_mask; // a bit being set means this bit is used for the blue color
                                        uint32_t reserved_mask; // a bit being set means this bit is not used by any of the red, green and blue colors
                                } pixel_info; // only valid if pixel_format is 2 (bitmask)
                                uint32_t pixels_per_scanline; // defines the number of pixel elements per video memory line
                        } efi_gop_mode_info_t;
                        typedef struct efi_gop_mode_s {
                                uint32_t max_mode; // number of modes supported by QueryMode() and SetMode()
                                uint32_t current_mode; // current Mode of the graphics device (0 to max_mode-1)
                                efi_gop_mode_info_t *info; // pointer to read-only efi_gop_mode_info_t data
                                _Uintn info_size; // size of info structure in bytes
                                uint64_t framebuffer_base; // base address of graphics linear frame buffer, where offset zero represents the upper left pixel of the display
                                _Uintn framebuffer_size; // amount of frame buffer needed to support the active mode as defined by PixelsPerScanLine x VerticalResolution x PixelElementSize
                        } efi_gop_mode_t;
                        typedef struct efi_gop_s {
                                EFI_STATUS (*QueryMode) (void *this_gop, uint32_t mode_number, _Uintn *info_size, efi_gop_mode_info_t **info);
                                EFI_STATUS (*SetMode) (void *this_gop, uint32_t mode_number);
                                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);
                                efi_gop_mode_t *mode; // pointer to efi_gop_mode_t data
                        } efi_gop_t;
                        efi_gop_t *gop = NULL;
                        EFI_GUID gop_guid = { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } }; // EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
                        if (efi_system_table->BootServices->LocateProtocol (&gop_guid, NULL, (void **) &gop) == 0) // obtain a pointer to the UEFI GOP API
                        {
                                _Uintn info_size;
                                efi_gop_mode_info_t *info;
                                EFI_STATUS status = gop->QueryMode (gop, (gop->mode == NULL ? 0 : gop->mode->current_mode), &info_size, &info); // obtain information about the current graphic mode
                                if (status == EFI_NOT_STARTED) // graphic output not started yet ?
                                {
                                        gop->SetMode (gop, 0); // initialize display with the first available mode if the UEFI program didn't do it already
                                        status = gop->QueryMode (gop, (gop->mode == NULL ? 0 : gop->mode->current_mode), &info_size, &info); // obtain information about the current graphic mode again
                                }
                                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 ?
                                {
                                        static char framebuffer_confstr[64] = ""; // keep allocations on the heap
                                        char *pixfmt_string = "none";
                                        if      (gop->mode->info->pixel_format == 0) pixfmt_string = "RGBx"; // only support 32-bit modes at the moment
                                        else if (gop->mode->info->pixel_format == 1) pixfmt_string = "BGRx"; // only support 32-bit modes at the moment
                                        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);
                                        add_typed_string (_CS_GRAPHICS, framebuffer_confstr); // save this configuration in the _CS_GRAPHICS configuration string
                                        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);
                                }
                                else
                                {
                                        static const char uefi_lfb_error2[] = "unable to get linear framebuffer default graphic mode information from EFI\n";
                                        kprintf (uefi_lfb_error2); // print error on kernel standard error
                                        uefi_print_str ((char *) uefi_lfb_error2); // and also on the EFI console
                                }
                        }
                        else
                        {
                                static const char uefi_lfb_error1[] = "unable to locate UEFI Graphic Output Protocol (no display?)\n";
                                kprintf (uefi_lfb_error1); // print error on kernel standard error
                                uefi_print_str ((char *) uefi_lfb_error1); // and also on the EFI console
                        }
                } // inject information about the current linear framebuffer used by the UEFI setup program -- END

Rebuild your BSP and use the _CS_GRAPHICS value from user-space to fire up a working UEFI console driver.

-- 
Pierre-Marie Baty <pm@pmbaty.com>