aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed/eboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/boot/compressed/eboot.c')
-rw-r--r--arch/x86/boot/compressed/eboot.c308
1 files changed, 1 insertions, 307 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 583d539a4197..52fef606bc54 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -571,312 +571,6 @@ free_handle:
571 efi_call_early(free_pool, pci_handle); 571 efi_call_early(free_pool, pci_handle);
572} 572}
573 573
574static void
575setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
576 struct efi_pixel_bitmask pixel_info, int pixel_format)
577{
578 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
579 si->lfb_depth = 32;
580 si->lfb_linelength = pixels_per_scan_line * 4;
581 si->red_size = 8;
582 si->red_pos = 0;
583 si->green_size = 8;
584 si->green_pos = 8;
585 si->blue_size = 8;
586 si->blue_pos = 16;
587 si->rsvd_size = 8;
588 si->rsvd_pos = 24;
589 } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) {
590 si->lfb_depth = 32;
591 si->lfb_linelength = pixels_per_scan_line * 4;
592 si->red_size = 8;
593 si->red_pos = 16;
594 si->green_size = 8;
595 si->green_pos = 8;
596 si->blue_size = 8;
597 si->blue_pos = 0;
598 si->rsvd_size = 8;
599 si->rsvd_pos = 24;
600 } else if (pixel_format == PIXEL_BIT_MASK) {
601 find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size);
602 find_bits(pixel_info.green_mask, &si->green_pos,
603 &si->green_size);
604 find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size);
605 find_bits(pixel_info.reserved_mask, &si->rsvd_pos,
606 &si->rsvd_size);
607 si->lfb_depth = si->red_size + si->green_size +
608 si->blue_size + si->rsvd_size;
609 si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8;
610 } else {
611 si->lfb_depth = 4;
612 si->lfb_linelength = si->lfb_width / 2;
613 si->red_size = 0;
614 si->red_pos = 0;
615 si->green_size = 0;
616 si->green_pos = 0;
617 si->blue_size = 0;
618 si->blue_pos = 0;
619 si->rsvd_size = 0;
620 si->rsvd_pos = 0;
621 }
622}
623
624static efi_status_t
625__gop_query32(struct efi_graphics_output_protocol_32 *gop32,
626 struct efi_graphics_output_mode_info **info,
627 unsigned long *size, u64 *fb_base)
628{
629 struct efi_graphics_output_protocol_mode_32 *mode;
630 efi_status_t status;
631 unsigned long m;
632
633 m = gop32->mode;
634 mode = (struct efi_graphics_output_protocol_mode_32 *)m;
635
636 status = efi_early->call(gop32->query_mode, gop32,
637 mode->mode, size, info);
638 if (status != EFI_SUCCESS)
639 return status;
640
641 *fb_base = mode->frame_buffer_base;
642 return status;
643}
644
645static efi_status_t
646setup_gop32(struct screen_info *si, efi_guid_t *proto,
647 unsigned long size, void **gop_handle)
648{
649 struct efi_graphics_output_protocol_32 *gop32, *first_gop;
650 unsigned long nr_gops;
651 u16 width, height;
652 u32 pixels_per_scan_line;
653 u32 ext_lfb_base;
654 u64 fb_base;
655 struct efi_pixel_bitmask pixel_info;
656 int pixel_format;
657 efi_status_t status;
658 u32 *handles = (u32 *)(unsigned long)gop_handle;
659 int i;
660
661 first_gop = NULL;
662 gop32 = NULL;
663
664 nr_gops = size / sizeof(u32);
665 for (i = 0; i < nr_gops; i++) {
666 struct efi_graphics_output_mode_info *info = NULL;
667 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
668 bool conout_found = false;
669 void *dummy = NULL;
670 u32 h = handles[i];
671 u64 current_fb_base;
672
673 status = efi_call_early(handle_protocol, h,
674 proto, (void **)&gop32);
675 if (status != EFI_SUCCESS)
676 continue;
677
678 status = efi_call_early(handle_protocol, h,
679 &conout_proto, &dummy);
680 if (status == EFI_SUCCESS)
681 conout_found = true;
682
683 status = __gop_query32(gop32, &info, &size, &current_fb_base);
684 if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
685 /*
686 * Systems that use the UEFI Console Splitter may
687 * provide multiple GOP devices, not all of which are
688 * backed by real hardware. The workaround is to search
689 * for a GOP implementing the ConOut protocol, and if
690 * one isn't found, to just fall back to the first GOP.
691 */
692 width = info->horizontal_resolution;
693 height = info->vertical_resolution;
694 pixel_format = info->pixel_format;
695 pixel_info = info->pixel_information;
696 pixels_per_scan_line = info->pixels_per_scan_line;
697 fb_base = current_fb_base;
698
699 /*
700 * Once we've found a GOP supporting ConOut,
701 * don't bother looking any further.
702 */
703 first_gop = gop32;
704 if (conout_found)
705 break;
706 }
707 }
708
709 /* Did we find any GOPs? */
710 if (!first_gop)
711 goto out;
712
713 /* EFI framebuffer */
714 si->orig_video_isVGA = VIDEO_TYPE_EFI;
715
716 si->lfb_width = width;
717 si->lfb_height = height;
718 si->lfb_base = fb_base;
719
720 ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
721 if (ext_lfb_base) {
722 si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
723 si->ext_lfb_base = ext_lfb_base;
724 }
725
726 si->pages = 1;
727
728 setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
729
730 si->lfb_size = si->lfb_linelength * si->lfb_height;
731
732 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
733out:
734 return status;
735}
736
737static efi_status_t
738__gop_query64(struct efi_graphics_output_protocol_64 *gop64,
739 struct efi_graphics_output_mode_info **info,
740 unsigned long *size, u64 *fb_base)
741{
742 struct efi_graphics_output_protocol_mode_64 *mode;
743 efi_status_t status;
744 unsigned long m;
745
746 m = gop64->mode;
747 mode = (struct efi_graphics_output_protocol_mode_64 *)m;
748
749 status = efi_early->call(gop64->query_mode, gop64,
750 mode->mode, size, info);
751 if (status != EFI_SUCCESS)
752 return status;
753
754 *fb_base = mode->frame_buffer_base;
755 return status;
756}
757
758static efi_status_t
759setup_gop64(struct screen_info *si, efi_guid_t *proto,
760 unsigned long size, void **gop_handle)
761{
762 struct efi_graphics_output_protocol_64 *gop64, *first_gop;
763 unsigned long nr_gops;
764 u16 width, height;
765 u32 pixels_per_scan_line;
766 u32 ext_lfb_base;
767 u64 fb_base;
768 struct efi_pixel_bitmask pixel_info;
769 int pixel_format;
770 efi_status_t status;
771 u64 *handles = (u64 *)(unsigned long)gop_handle;
772 int i;
773
774 first_gop = NULL;
775 gop64 = NULL;
776
777 nr_gops = size / sizeof(u64);
778 for (i = 0; i < nr_gops; i++) {
779 struct efi_graphics_output_mode_info *info = NULL;
780 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
781 bool conout_found = false;
782 void *dummy = NULL;
783 u64 h = handles[i];
784 u64 current_fb_base;
785
786 status = efi_call_early(handle_protocol, h,
787 proto, (void **)&gop64);
788 if (status != EFI_SUCCESS)
789 continue;
790
791 status = efi_call_early(handle_protocol, h,
792 &conout_proto, &dummy);
793 if (status == EFI_SUCCESS)
794 conout_found = true;
795
796 status = __gop_query64(gop64, &info, &size, &current_fb_base);
797 if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
798 /*
799 * Systems that use the UEFI Console Splitter may
800 * provide multiple GOP devices, not all of which are
801 * backed by real hardware. The workaround is to search
802 * for a GOP implementing the ConOut protocol, and if
803 * one isn't found, to just fall back to the first GOP.
804 */
805 width = info->horizontal_resolution;
806 height = info->vertical_resolution;
807 pixel_format = info->pixel_format;
808 pixel_info = info->pixel_information;
809 pixels_per_scan_line = info->pixels_per_scan_line;
810 fb_base = current_fb_base;
811
812 /*
813 * Once we've found a GOP supporting ConOut,
814 * don't bother looking any further.
815 */
816 first_gop = gop64;
817 if (conout_found)
818 break;
819 }
820 }
821
822 /* Did we find any GOPs? */
823 if (!first_gop)
824 goto out;
825
826 /* EFI framebuffer */
827 si->orig_video_isVGA = VIDEO_TYPE_EFI;
828
829 si->lfb_width = width;
830 si->lfb_height = height;
831 si->lfb_base = fb_base;
832
833 ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
834 if (ext_lfb_base) {
835 si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
836 si->ext_lfb_base = ext_lfb_base;
837 }
838
839 si->pages = 1;
840
841 setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
842
843 si->lfb_size = si->lfb_linelength * si->lfb_height;
844
845 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
846out:
847 return status;
848}
849
850/*
851 * See if we have Graphics Output Protocol
852 */
853static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
854 unsigned long size)
855{
856 efi_status_t status;
857 void **gop_handle = NULL;
858
859 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
860 size, (void **)&gop_handle);
861 if (status != EFI_SUCCESS)
862 return status;
863
864 status = efi_call_early(locate_handle,
865 EFI_LOCATE_BY_PROTOCOL,
866 proto, NULL, &size, gop_handle);
867 if (status != EFI_SUCCESS)
868 goto free_handle;
869
870 if (efi_early->is64)
871 status = setup_gop64(si, proto, size, gop_handle);
872 else
873 status = setup_gop32(si, proto, size, gop_handle);
874
875free_handle:
876 efi_call_early(free_pool, gop_handle);
877 return status;
878}
879
880static efi_status_t 574static efi_status_t
881setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) 575setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
882{ 576{
@@ -1038,7 +732,7 @@ void setup_graphics(struct boot_params *boot_params)
1038 EFI_LOCATE_BY_PROTOCOL, 732 EFI_LOCATE_BY_PROTOCOL,
1039 &graphics_proto, NULL, &size, gop_handle); 733 &graphics_proto, NULL, &size, gop_handle);
1040 if (status == EFI_BUFFER_TOO_SMALL) 734 if (status == EFI_BUFFER_TOO_SMALL)
1041 status = setup_gop(si, &graphics_proto, size); 735 status = efi_setup_gop(NULL, si, &graphics_proto, size);
1042 736
1043 if (status != EFI_SUCCESS) { 737 if (status != EFI_SUCCESS) {
1044 size = 0; 738 size = 0;