--- old/usr/src/uts/i86pc/os/ddi_impl.c	Mon Aug  5 17:37:25 2019
+++ new/usr/src/uts/i86pc/os/ddi_impl.c	Mon Aug  5 17:37:25 2019
@@ -68,6 +68,7 @@
 #include <vm/hat_i86.h>
 #include <sys/x86_archext.h>
 #include <sys/avl.h>
+#include <sys/font.h>
 
 /*
  * DDI Boot Configuration
@@ -1841,7 +1842,7 @@
 	extern char hw_provider[];
 	dev_info_t *devi;
 	char *name;
-	int length;
+	int length, flags;
 	char property_name[50], property_val[50];
 	void *bop_staging_area;
 
@@ -1872,7 +1873,7 @@
 		}
 
 		length = BOP_GETPROPLEN(bootops, property_name);
-		if (length == 0)
+		if (length < 0)
 			continue;
 		if (length > MMU_PAGESIZE) {
 			cmn_err(CE_NOTE,
@@ -1881,6 +1882,7 @@
 			continue;
 		}
 		BOP_GETPROP(bootops, property_name, bop_staging_area);
+		flags = do_bsys_getproptype(bootops, property_name);
 
 		/*
 		 * special properties:
@@ -1895,54 +1897,67 @@
 		if (strcmp(name, "si-machine") == 0) {
 			(void) strncpy(utsname.machine, bop_staging_area,
 			    SYS_NMLN);
-			utsname.machine[SYS_NMLN - 1] = (char)NULL;
-		} else if (strcmp(name, "si-hw-provider") == 0) {
+			utsname.machine[SYS_NMLN - 1] = '\0';
+			continue;
+		}
+		if (strcmp(name, "si-hw-provider") == 0) {
 			(void) strncpy(hw_provider, bop_staging_area, SYS_NMLN);
-			hw_provider[SYS_NMLN - 1] = (char)NULL;
-		} else if (strcmp(name, "bios-boot-device") == 0) {
+			hw_provider[SYS_NMLN - 1] = '\0';
+			continue;
+		}
+		if (strcmp(name, "bios-boot-device") == 0) {
 			copy_boot_str(bop_staging_area, property_val, 50);
 			(void) ndi_prop_update_string(DDI_DEV_T_NONE, devi,
 			    property_name, property_val);
-		} else if (strcmp(name, "acpi-root-tab") == 0) {
-			(void) ndi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strcmp(name, "smbios-address") == 0) {
-			(void) ndi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strcmp(name, "efi-systab") == 0) {
-			(void) ndi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strcmp(name, "efi-systype") == 0) {
-			copy_boot_str(bop_staging_area, property_val, 50);
-			(void) ndi_prop_update_string(DDI_DEV_T_NONE, devi,
-			    property_name, property_val);
-		} else if (strcmp(name, "stdout") == 0) {
+			continue;
+		}
+		if (strcmp(name, "stdout") == 0) {
 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, devi,
 			    property_name, *((int *)bop_staging_area));
-		} else if (strcmp(name, "boot-args") == 0) {
-			copy_boot_str(bop_staging_area, property_val, 50);
+			continue;
+		}
+
+		/* Boolean property */
+		if (length == 0) {
+			(void) e_ddi_prop_create(DDI_DEV_T_NONE, devi,
+			    DDI_PROP_CANSLEEP, property_name, NULL, 0);
+			continue;
+		}
+
+		/* Now anything else based on type. */
+		switch (flags) {
+		case DDI_PROP_TYPE_INT:
+			if (length == sizeof (int)) {
+				(void) e_ddi_prop_update_int(DDI_DEV_T_NONE,
+				    devi, property_name,
+				    *((int *)bop_staging_area));
+			} else {
+				(void) e_ddi_prop_update_int_array(
+				    DDI_DEV_T_NONE, devi, property_name,
+				    bop_staging_area, length / sizeof (int));
+			}
+			break;
+		case DDI_PROP_TYPE_STRING:
 			(void) e_ddi_prop_update_string(DDI_DEV_T_NONE, devi,
-			    property_name, property_val);
-		} else if (strcmp(name, "bootargs") == 0) {
-			copy_boot_str(bop_staging_area, property_val, 50);
-			(void) e_ddi_prop_update_string(DDI_DEV_T_NONE, devi,
-			    property_name, property_val);
-		} else if (strcmp(name, "bootp-response") == 0) {
+			    property_name, bop_staging_area);
+			break;
+		case DDI_PROP_TYPE_BYTE:
 			(void) e_ddi_prop_update_byte_array(DDI_DEV_T_NONE,
 			    devi, property_name, bop_staging_area, length);
-		} else if (strcmp(name, "ramdisk_start") == 0) {
-			(void) e_ddi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strcmp(name, "ramdisk_end") == 0) {
-			(void) e_ddi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strncmp(name, "module-addr-", 12) == 0) {
-			(void) e_ddi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else if (strncmp(name, "module-size-", 12) == 0) {
-			(void) e_ddi_prop_update_int64(DDI_DEV_T_NONE, devi,
-			    property_name, *((int64_t *)bop_staging_area));
-		} else {
+			break;
+		case DDI_PROP_TYPE_INT64:
+			if (length == sizeof (uint64_t)) {
+				(void) e_ddi_prop_update_int64(DDI_DEV_T_NONE,
+				    devi, property_name,
+				    *((uint64_t *)bop_staging_area));
+			} else {
+				(void) e_ddi_prop_update_int64_array(
+				    DDI_DEV_T_NONE, devi, property_name,
+				    bop_staging_area,
+				    length / sizeof (uint64_t));
+			}
+			break;
+		default:
 			/* Property type unknown, use old prop interface */
 			(void) e_ddi_prop_create(DDI_DEV_T_NONE, devi,
 			    DDI_PROP_CANSLEEP, property_name, bop_staging_area,
@@ -2018,7 +2033,56 @@
 	kmem_free(bop_staging_area, MMU_PAGESIZE);
 }
 
+/*
+ * Copy console font to kernel memory. The temporary font setup
+ * to use font module was done in early console setup, using low
+ * memory and data from font module. Now we need to allocate
+ * kernel memory and copy data over, so the low memory can be freed.
+ * We can have at most one entry in font list from early boot.
+ */
+static void
+get_console_font(void)
+{
+	struct fontlist *fp, *fl;
+	bitmap_data_t *bd;
+	struct font *fd, *tmp;
+	int i;
 
+	if (STAILQ_EMPTY(&fonts))
+		return;
+
+	fl = STAILQ_FIRST(&fonts);
+	STAILQ_REMOVE_HEAD(&fonts, font_next);
+	fp = kmem_zalloc(sizeof (*fp), KM_SLEEP);
+	bd = kmem_zalloc(sizeof (*bd), KM_SLEEP);
+	fd = kmem_zalloc(sizeof (*fd), KM_SLEEP);
+
+	fp->font_name = NULL;
+	fp->font_flags = FONT_BOOT;
+	fp->font_data = bd;
+
+	bd->width = fl->font_data->width;
+	bd->height = fl->font_data->height;
+	bd->uncompressed_size = fl->font_data->uncompressed_size;
+	bd->font = fd;
+
+	tmp = fl->font_data->font;
+	fd->vf_width = tmp->vf_width;
+	fd->vf_height = tmp->vf_height;
+	for (i = 0; i < VFNT_MAPS; i++) {
+		if (tmp->vf_map_count[i] == 0)
+			continue;
+		fd->vf_map_count[i] = tmp->vf_map_count[i];
+		fd->vf_map[i] = kmem_alloc(fd->vf_map_count[i] *
+		    sizeof (*fd->vf_map[i]), KM_SLEEP);
+		bcopy(tmp->vf_map[i], fd->vf_map[i], fd->vf_map_count[i] *
+		    sizeof (*fd->vf_map[i]));
+	}
+	fd->vf_bytes = kmem_alloc(bd->uncompressed_size, KM_SLEEP);
+	bcopy(tmp->vf_bytes, fd->vf_bytes, bd->uncompressed_size);
+	STAILQ_INSERT_HEAD(&fonts, fp, font_next);
+}
+
 /*
  * This is temporary, but absolutely necessary.  If we are being
  * booted with a device tree created by the DevConf project's bootconf
@@ -2570,6 +2634,9 @@
 	/* not framebuffer should be enumerated, if present */
 	get_vga_properties();
 
+	/* Copy console font if provided by boot. */
+	get_console_font();
+
 	/*
 	 * Check for administratively disabled drivers.
 	 */
