Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

@@ -34,10 +34,11 @@
 #include <sys/mach_mmu.h>
 #include <sys/multiboot.h>
 #include <sys/multiboot2.h>
 #include <sys/multiboot2_impl.h>
 #include <sys/sysmacros.h>
+#include <sys/framebuffer.h>
 #include <sys/sha1.h>
 #include <util/string.h>
 #include <util/strtolctype.h>
 #include <sys/efi.h>
 

@@ -135,10 +136,12 @@
 multiboot2_info_header_t *mb2_info;
 multiboot_tag_mmap_t *mb2_mmap_tagp;
 int num_entries;                        /* mmap entry count */
 boolean_t num_entries_set;              /* is mmap entry count set */
 uintptr_t load_addr;
+static boot_framebuffer_t framebuffer[2];
+static boot_framebuffer_t *fb;
 
 /* can not be automatic variables because of alignment */
 static efi_guid_t smbios3 = SMBIOS3_TABLE_GUID;
 static efi_guid_t smbios = SMBIOS_TABLE_GUID;
 static efi_guid_t acpi2 = EFI_ACPI_TABLE_GUID;

@@ -162,10 +165,11 @@
 int amd64_support = 0;
 int largepage_support = 0;
 int pae_support = 0;
 int pge_support = 0;
 int NX_support = 0;
+int PAT_support = 0;
 
 /*
  * Low 32 bits of kernel entry address passed back to assembler.
  * When running a 64 bit kernel, the high 32 bits are 0xffffffff.
  */

@@ -971,20 +975,21 @@
 #else   /* !__xpv */
 
 static void
 dboot_multiboot1_xboot_consinfo(void)
 {
-        bi->bi_framebuffer = NULL;
+        fb->framebuffer = 0;
 }
 
 static void
 dboot_multiboot2_xboot_consinfo(void)
 {
-        multiboot_tag_framebuffer_t *fb;
-        fb = dboot_multiboot2_find_tag(mb2_info,
+        multiboot_tag_framebuffer_t *fbtag;
+        fbtag = dboot_multiboot2_find_tag(mb2_info,
             MULTIBOOT_TAG_TYPE_FRAMEBUFFER);
-        bi->bi_framebuffer = (native_ptr_t)(uintptr_t)fb;
+        fb->framebuffer = (uint64_t)(uintptr_t)fbtag;
+        fb->boot_fb_virt = 0;
 }
 
 static int
 dboot_multiboot_modcount(void)
 {

@@ -1057,46 +1062,52 @@
         }
         return (0);
 }
 
 /*
- * Find the environment module for console setup.
+ * Find the modules used by console setup.
  * Since we need the console to print early boot messages, the console is set up
- * before anything else and therefore we need to pick up the environment module
- * early too.
+ * before anything else and therefore we need to pick up the needed modules.
  *
- * Note, we just will search for and if found, will pass the env
- * module to console setup, the proper module list processing will happen later.
+ * Note, we just will search for and if found, will pass the modules
+ * to console setup, the proper module list processing will happen later.
+ * Currenly used modules are boot environment and consoler font.
  */
 static void
-dboot_find_env(void)
+dboot_find_console_modules(void)
 {
         int i, modcount;
         uint32_t mod_start, mod_end;
         char *cmdline;
 
         modcount = dboot_multiboot_modcount();
-
+        bi->bi_module_cnt = 0;
         for (i = 0; i < modcount; ++i) {
                 cmdline = dboot_multiboot_modcmdline(i);
                 if (cmdline == NULL)
                         continue;
 
-                if (strstr(cmdline, "type=environment") == NULL)
+                if (strstr(cmdline, "type=console-font") != NULL)
+                        modules[bi->bi_module_cnt].bm_type = BMT_FONT;
+                else if (strstr(cmdline, "type=environment") != NULL)
+                        modules[bi->bi_module_cnt].bm_type = BMT_ENV;
+                else
                         continue;
 
                 mod_start = dboot_multiboot_modstart(i);
                 mod_end = dboot_multiboot_modend(i);
-                modules[0].bm_addr = (native_ptr_t)(uintptr_t)mod_start;
-                modules[0].bm_size = mod_end - mod_start;
-                modules[0].bm_name = (native_ptr_t)(uintptr_t)NULL;
-                modules[0].bm_hash = (native_ptr_t)(uintptr_t)NULL;
-                modules[0].bm_type = BMT_ENV;
-                bi->bi_modules = (native_ptr_t)(uintptr_t)modules;
-                bi->bi_module_cnt = 1;
-                return;
+                modules[bi->bi_module_cnt].bm_addr =
+                    (native_ptr_t)(uintptr_t)mod_start;
+                modules[bi->bi_module_cnt].bm_size = mod_end - mod_start;
+                modules[bi->bi_module_cnt].bm_name =
+                    (native_ptr_t)(uintptr_t)NULL;
+                modules[bi->bi_module_cnt].bm_hash =
+                    (native_ptr_t)(uintptr_t)NULL;
+                bi->bi_module_cnt++;
         }
+        if (bi->bi_module_cnt != 0)
+                bi->bi_modules = (native_ptr_t)(uintptr_t)modules;
 }
 
 static boolean_t
 dboot_multiboot_basicmeminfo(uint32_t *lower, uint32_t *upper)
 {

@@ -1193,10 +1204,12 @@
                 return ("file");
         case BMT_HASH:
                 return ("hash");
         case BMT_ENV:
                 return ("environment");
+        case BMT_FONT:
+                return ("console-font");
         default:
                 return ("unknown");
         }
 }
 

@@ -1313,10 +1326,12 @@
                                 modules[midx].bm_type = BMT_ROOTFS;
                         } else if (strcmp(q, "hash") == 0) {
                                 modules[midx].bm_type = BMT_HASH;
                         } else if (strcmp(q, "environment") == 0) {
                                 modules[midx].bm_type = BMT_ENV;
+                        } else if (strcmp(q, "console-font") == 0) {
+                                modules[midx].bm_type = BMT_FONT;
                         } else if (strcmp(q, "file") != 0) {
                                 dboot_printf("\tmodule #%d: unknown module "
                                     "type '%s'; defaulting to 'file'",
                                     midx, q);
                         }

@@ -2020,26 +2035,49 @@
 
         /*
          * Map framebuffer memory as PT_NOCACHE as this is memory from a
          * device and therefore must not be cached.
          */
-        if (bi->bi_framebuffer != NULL) {
-                multiboot_tag_framebuffer_t *fb;
-                fb = (multiboot_tag_framebuffer_t *)(uintptr_t)
-                    bi->bi_framebuffer;
+        if (fb != NULL && fb->framebuffer != 0) {
+                multiboot_tag_framebuffer_t *fb_tagp;
+                fb_tagp = (multiboot_tag_framebuffer_t *)(uintptr_t)
+                    fb->framebuffer;
 
-                start = fb->framebuffer_common.framebuffer_addr;
-                end = start + fb->framebuffer_common.framebuffer_height *
-                    fb->framebuffer_common.framebuffer_pitch;
+                start = fb_tagp->framebuffer_common.framebuffer_addr;
+                end = start + fb_tagp->framebuffer_common.framebuffer_height *
+                    fb_tagp->framebuffer_common.framebuffer_pitch;
 
+                /* VGA text memory is already mapped. */
+                if (fb_tagp->framebuffer_common.framebuffer_type !=
+                    MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT) {
+                        uint64_t vaddr;
+
+#if defined(_BOOT_TARGET_amd64)
+                        vaddr = start;
+#else
+                        vaddr = (uintptr_t)mem_alloc(end - start);
+#endif
+                        fb->boot_fb_virt = vaddr;
+                        if (map_debug) {
+                                dboot_printf("FB map pa=%" PRIx64 "..%"
+                                    PRIx64 "\n", start, end);
+                        }
+
                 pte_bits |= PT_NOCACHE;
+                        if (PAT_support != 0)
+                                pte_bits |= PT_PAT_4K;
+
                 while (start < end) {
-                        map_pa_at_va(start, start, 0);
+                                map_pa_at_va(start, vaddr, 0);
                         start += MMU_PAGESIZE;
+                                vaddr += MMU_PAGESIZE;
                 }
                 pte_bits &= ~PT_NOCACHE;
+                        if (PAT_support != 0)
+                                pte_bits &= ~PT_PAT_4K;
         }
+        }
 #endif /* !__xpv */
 
         DBG_MSG("\nPage tables constructed\n");
 }
 

@@ -2060,10 +2098,18 @@
         addr = (uintptr_t)boot_info;
         addr = (addr + 0xf) & ~0xf;
         bi = (struct xboot_info *)addr;
 
 #if !defined(__xpv)
+        /*
+         * fb info must be 16 byte aligned for 64 bit kernel ABI
+         */
+        addr = (uintptr_t)framebuffer;
+        addr = (addr + 0xf) & ~0xf;
+        fb = (boot_framebuffer_t *)addr;
+        bi->bi_framebuffer = (native_ptr_t)(uintptr_t)fb;
+
         switch (multiboot_version) {
         case 1:
                 dboot_multiboot1_xboot_consinfo();
                 break;
         case 2:

@@ -2076,11 +2122,11 @@
         }
         /*
          * Lookup environment module for the console. Complete module list
          * will be built after console setup.
          */
-        dboot_find_env();
+        dboot_find_console_modules();
 #endif
 }
 
 /*
  * Set up basic data from the boot loader.

@@ -2200,10 +2246,11 @@
         char *bootloader;
 #if defined(__xpv)
         physdev_set_iopl_t set_iopl;
 #endif /* __xpv */
 
+        bcons_init(NULL);       /* Set very early console to ttya. */
         dboot_loader_init();
         /*
          * At this point we are executing in a 32 bit real mode.
          */
 

@@ -2221,11 +2268,11 @@
         }
 #endif /* __xpv */
 
         dboot_init_xboot_consinfo();
         bi->bi_cmdline = (native_ptr_t)(uintptr_t)cmdline;
-        bcons_init(bi);
+        bcons_init(bi);         /* Now we can set the real console. */
 
         prom_debug = (find_boot_prop("prom_debug") != NULL);
         map_debug = (find_boot_prop("map_debug") != NULL);
 
 #if !defined(__xpv)

@@ -2347,10 +2394,20 @@
                         if (edx & CPUID_AMD_EDX_NX)
                                 NX_support = 1;
                 }
         }
 
+        /*
+         * check for PAT support
+         */
+        {
+                uint32_t eax = 1;
+                uint32_t edx = get_cpuid_edx(&eax);
+
+                if (edx & CPUID_INTC_EDX_PAT)
+                        PAT_support = 1;
+        }
 #if !defined(_BOOT_TARGET_amd64)
 
         /*
          * The 32-bit hypervisor uses segmentation to protect itself from
          * guests. This means when a guest attempts to install a flat 4GB

@@ -2388,10 +2445,12 @@
                         largepage_support = 1;
                 if (edx & CPUID_INTC_EDX_PGE)
                         pge_support = 1;
                 if (edx & CPUID_INTC_EDX_PAE)
                         pae_support = 1;
+                if (edx & CPUID_INTC_EDX_PAT)
+                        PAT_support = 1;
 
                 eax = 0x80000000;
                 edx = get_cpuid_edx(&eax);
                 if (eax >= 0x80000001) {
                         eax = 0x80000001;

@@ -2457,10 +2516,11 @@
                 pte_size = 4;
                 lpagesize = FOUR_MEG;
                 top_level = 1;
         }
 
+        DBG(PAT_support);
         DBG(pge_support);
         DBG(NX_support);
         DBG(largepage_support);
         DBG(amd64_support);
         DBG(top_level);

@@ -2556,7 +2616,16 @@
 #ifndef __xpv
         if (map_debug)
                 dump_tables();
 #endif
 
+#ifndef __xpv
+        /* Update boot info with FB data */
+        fb->cursor.origin.x = fb_info.cursor.origin.x;
+        fb->cursor.origin.y = fb_info.cursor.origin.y;
+        fb->cursor.pos.x = fb_info.cursor.pos.x;
+        fb->cursor.pos.y = fb_info.cursor.pos.y;
+        fb->cursor.visible = fb_info.cursor.visible;
+#endif
+
         DBG_MSG("\n\n*** DBOOT DONE -- back to asm to jump to kernel\n\n");
 }