Index: sys/boot/efi/loader/main.c
===================================================================
--- sys/boot/efi/loader/main.c
+++ sys/boot/efi/loader/main.c
@@ -66,6 +66,7 @@
 EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
 EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
 EFI_GUID fdtdtb = FDT_TABLE_GUID;
+EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
 
 #ifdef EFI_ZFS_BOOT
 static void efi_zfs_probe(void);
@@ -94,6 +95,83 @@
 		dst[i] = (char)src[i];
 }
 
+static int
+has_keyboard(void)
+{
+	EFI_STATUS status;
+	EFI_DEVICE_PATH *path;
+	EFI_HANDLE *hin, *hin_end, *walker;
+	UINTN sz;
+	int retval = 0;
+	
+	/*
+	 * Find all the hanldes that support the SIMPLE_TEXT_INPUT_PROTOCOL
+	 * and do the typical dance to get the right sized buffer.
+	 */
+	sz = 0;
+	hin = NULL;
+	status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0);
+	if (status == EFI_BUFFER_TOO_SMALL) {
+		hin = (EFI_HANDLE *)malloc(sz);
+		status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz,
+		    hin);
+		if (EFI_ERROR(status))
+			free(hin);
+	}
+	if (EFI_ERROR(status))
+		return retval;
+
+	/*
+	 * Look at teach of the handles. If it supports the device path
+	 * protocol, use it to get the device path for this handle. Then
+	 * see if that device path matches either the USB device path
+	 * for keyboards or the legacy device path for keyboards.
+	 */
+	hin_end = &hin[sz / sizeof(*hin)];
+	for (walker = hin; walker < hin_end; walker++) {
+		status = BS->HandleProtocol(*walker, &devid, (VOID **)&path);
+		if (EFI_ERROR(status))
+			continue;
+
+		while (!IsDevicePathEnd(path)) {
+			/*
+			 * Check for the ACPI keyboard node. All PNP3xx nodes
+			 * are keyboards of different flavors.
+			 */
+			if (DevicePathType(path) == ACPI_DEVICE_PATH &&
+			    (DevicePathSubType(path) == ACPI_DP ||
+				DevicePathSubType(path) == ACPI_EXTENDED_DP)) {
+				ACPI_HID_DEVICE_PATH  *acpi;
+
+				acpi = (ACPI_HID_DEVICE_PATH *)(void *)path;
+				if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 &&
+				    (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) {
+					retval = 1;
+					goto out;
+				}
+			/*
+			 * Check for USB keyboard node, if present.
+			 */
+			} else if (DevicePathType(path) == MESSAGING_DEVICE_PATH &&
+			    DevicePathSubType(path) == MSG_USB_CLASS_DP) {
+				USB_CLASS_DEVICE_PATH *usb;
+			       
+				usb = (USB_CLASS_DEVICE_PATH *)(void *)path;
+				if (usb->DeviceClass == 3 && /* HID */
+				    usb->DeviceSubClass == 1 && /* Boot devices */
+				    usb->DeviceProtocol == 1) { /* Boot keyboards */
+					retval = 1;
+					goto out;
+				}
+			}
+			path = NextDevicePathNode(path);
+		}
+	}
+out:
+	free(hin);
+	return retval;
+}
+
 EFI_STATUS
 main(int argc, CHAR16 *argv[])
 {
@@ -104,6 +182,7 @@
 	struct devsw *dev;
 	uint64_t pool_guid;
 	UINTN k;
+	int has_kbd;
 
 	archsw.arch_autoload = efi_autoload;
 	archsw.arch_getdev = efi_getdev;
@@ -115,6 +194,8 @@
 	archsw.arch_zfs_probe = efi_zfs_probe;
 #endif
 
+	has_kbd = has_keyboard();
+
 	/*
 	 * XXX Chicken-and-egg problem; we want to have console output
 	 * early, but some console attributes may depend on reading from
@@ -150,15 +231,19 @@
 				case 'D':
 					howto |= RB_MULTIPLE;
 					break;
+				case 'h':
+					howto |= RB_SERIAL;
+					break;
 				case 'm':
 					howto |= RB_MUTE;
 					break;
-				case 'h':
-					howto |= RB_SERIAL;
-					break;
 				case 'p':
 					howto |= RB_PAUSE;
 					break;
+				case 'P':
+					if (!has_kbd)
+						howto |= RB_SERIAL | RB_MULTIPLE;
+					break;
 				case 'r':
 					howto |= RB_DFLTROOT;
 					break;