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,43 ****
--- 34,44 ----
  #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,144 ****
--- 136,147 ----
  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,171 ****
--- 165,175 ----
  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,990 ****
  #else   /* !__xpv */
  
  static void
  dboot_multiboot1_xboot_consinfo(void)
  {
!         bi->bi_framebuffer = NULL;
  }
  
  static void
  dboot_multiboot2_xboot_consinfo(void)
  {
!         multiboot_tag_framebuffer_t *fb;
!         fb = dboot_multiboot2_find_tag(mb2_info,
              MULTIBOOT_TAG_TYPE_FRAMEBUFFER);
!         bi->bi_framebuffer = (native_ptr_t)(uintptr_t)fb;
  }
  
  static int
  dboot_multiboot_modcount(void)
  {
--- 975,995 ----
  #else   /* !__xpv */
  
  static void
  dboot_multiboot1_xboot_consinfo(void)
  {
!         fb->framebuffer = 0;
  }
  
  static void
  dboot_multiboot2_xboot_consinfo(void)
  {
!         multiboot_tag_framebuffer_t *fbtag;
!         fbtag = dboot_multiboot2_find_tag(mb2_info,
              MULTIBOOT_TAG_TYPE_FRAMEBUFFER);
!         fb->framebuffer = (uint64_t)(uintptr_t)fbtag;
!         fb->boot_fb_virt = 0;
  }
  
  static int
  dboot_multiboot_modcount(void)
  {
*** 1057,1102 ****
          }
          return (0);
  }
  
  /*
!  * Find the environment module for 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.
   *
!  * 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.
   */
  static void
! dboot_find_env(void)
  {
          int i, modcount;
          uint32_t mod_start, mod_end;
          char *cmdline;
  
          modcount = dboot_multiboot_modcount();
! 
          for (i = 0; i < modcount; ++i) {
                  cmdline = dboot_multiboot_modcmdline(i);
                  if (cmdline == NULL)
                          continue;
  
!                 if (strstr(cmdline, "type=environment") == NULL)
                          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;
          }
  }
  
  static boolean_t
  dboot_multiboot_basicmeminfo(uint32_t *lower, uint32_t *upper)
  {
--- 1062,1113 ----
          }
          return (0);
  }
  
  /*
!  * 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 needed modules.
   *
!  * 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_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=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[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,1202 ****
--- 1204,1215 ----
                  return ("file");
          case BMT_HASH:
                  return ("hash");
          case BMT_ENV:
                  return ("environment");
+         case BMT_FONT:
+                 return ("console-font");
          default:
                  return ("unknown");
          }
  }
  
*** 1313,1322 ****
--- 1326,1337 ----
                                  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,2045 ****
  
          /*
           * 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;
  
!                 start = fb->framebuffer_common.framebuffer_addr;
!                 end = start + fb->framebuffer_common.framebuffer_height *
!                     fb->framebuffer_common.framebuffer_pitch;
  
                  pte_bits |= PT_NOCACHE;
                  while (start < end) {
!                         map_pa_at_va(start, start, 0);
                          start += MMU_PAGESIZE;
                  }
                  pte_bits &= ~PT_NOCACHE;
          }
  #endif /* !__xpv */
  
          DBG_MSG("\nPage tables constructed\n");
  }
  
--- 2035,2083 ----
  
          /*
           * Map framebuffer memory as PT_NOCACHE as this is memory from a
           * device and therefore must not be cached.
           */
!         if (fb != NULL && fb->framebuffer != 0) {
!                 multiboot_tag_framebuffer_t *fb_tagp;
!                 fb_tagp = (multiboot_tag_framebuffer_t *)(uintptr_t)
!                     fb->framebuffer;
  
!                 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, 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,2069 ****
--- 2098,2115 ----
          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,2086 ****
          }
          /*
           * Lookup environment module for the console. Complete module list
           * will be built after console setup.
           */
!         dboot_find_env();
  #endif
  }
  
  /*
   * Set up basic data from the boot loader.
--- 2122,2132 ----
          }
          /*
           * Lookup environment module for the console. Complete module list
           * will be built after console setup.
           */
!         dboot_find_console_modules();
  #endif
  }
  
  /*
   * Set up basic data from the boot loader.
*** 2200,2209 ****
--- 2246,2256 ----
          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,2231 ****
          }
  #endif /* __xpv */
  
          dboot_init_xboot_consinfo();
          bi->bi_cmdline = (native_ptr_t)(uintptr_t)cmdline;
!         bcons_init(bi);
  
          prom_debug = (find_boot_prop("prom_debug") != NULL);
          map_debug = (find_boot_prop("map_debug") != NULL);
  
  #if !defined(__xpv)
--- 2268,2278 ----
          }
  #endif /* __xpv */
  
          dboot_init_xboot_consinfo();
          bi->bi_cmdline = (native_ptr_t)(uintptr_t)cmdline;
!         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,2356 ****
--- 2394,2413 ----
                          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,2397 ****
--- 2445,2456 ----
                          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,2466 ****
--- 2516,2526 ----
                  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,2562 ****
--- 2616,2631 ----
  #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");
  }