efi_loader: Uart device path
When uploading an EFI binary via the UART we need to assign a device path. * Provide devicepath node to text conversion for Uart() node. * Provide function to create Uart() device path. * Add UART support to efi_dp_from_name(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
		
							parent
							
								
									a95f4c8859
								
							
						
					
					
						commit
						62df6e9c99
					
				|  | @ -523,6 +523,7 @@ struct efi_device_path_acpi_path { | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_SCSI		0x02 | #  define DEVICE_PATH_SUB_TYPE_MSG_SCSI		0x02 | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_USB		0x05 | #  define DEVICE_PATH_SUB_TYPE_MSG_USB		0x05 | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR	0x0b | #  define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR	0x0b | ||||||
|  | #  define DEVICE_PATH_SUB_TYPE_MSG_UART		0x0e | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS	0x0f | #  define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS	0x0f | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_SATA		0x12 | #  define DEVICE_PATH_SUB_TYPE_MSG_SATA		0x12 | ||||||
| #  define DEVICE_PATH_SUB_TYPE_MSG_NVME		0x17 | #  define DEVICE_PATH_SUB_TYPE_MSG_NVME		0x17 | ||||||
|  | @ -542,6 +543,15 @@ struct efi_device_path_scsi { | ||||||
| 	u16 logical_unit_number; | 	u16 logical_unit_number; | ||||||
| } __packed; | } __packed; | ||||||
| 
 | 
 | ||||||
|  | struct efi_device_path_uart { | ||||||
|  | 	struct efi_device_path dp; | ||||||
|  | 	u32 reserved; | ||||||
|  | 	u64 baud_rate; | ||||||
|  | 	u8 data_bits; | ||||||
|  | 	u8 parity; | ||||||
|  | 	u8 stop_bits; | ||||||
|  | } __packed; | ||||||
|  | 
 | ||||||
| struct efi_device_path_usb { | struct efi_device_path_usb { | ||||||
| 	struct efi_device_path dp; | 	struct efi_device_path dp; | ||||||
| 	u8 parent_port_number; | 	u8 parent_port_number; | ||||||
|  |  | ||||||
|  | @ -960,6 +960,28 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, | ||||||
| 	return start; | 	return start; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct efi_device_path *efi_dp_from_uart(void) | ||||||
|  | { | ||||||
|  | 	void *buf, *pos; | ||||||
|  | 	struct efi_device_path_uart *uart; | ||||||
|  | 	size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END); | ||||||
|  | 
 | ||||||
|  | 	buf = dp_alloc(dpsize); | ||||||
|  | 	if (!buf) | ||||||
|  | 		return NULL; | ||||||
|  | 	pos = buf; | ||||||
|  | 	memcpy(pos, &ROOT, sizeof(ROOT)); | ||||||
|  | 	pos += sizeof(ROOT); | ||||||
|  | 	uart = pos; | ||||||
|  | 	uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; | ||||||
|  | 	uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART; | ||||||
|  | 	uart->dp.length = sizeof(*uart); | ||||||
|  | 	pos += sizeof(*uart); | ||||||
|  | 	memcpy(pos, &END, sizeof(END)); | ||||||
|  | 
 | ||||||
|  | 	return buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifdef CONFIG_NET | #ifdef CONFIG_NET | ||||||
| struct efi_device_path *efi_dp_from_eth(void) | struct efi_device_path *efi_dp_from_eth(void) | ||||||
| { | { | ||||||
|  | @ -1086,7 +1108,6 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, | ||||||
| 			      struct efi_device_path **device, | 			      struct efi_device_path **device, | ||||||
| 			      struct efi_device_path **file) | 			      struct efi_device_path **file) | ||||||
| { | { | ||||||
| 	int is_net; |  | ||||||
| 	struct blk_desc *desc = NULL; | 	struct blk_desc *desc = NULL; | ||||||
| 	struct disk_partition fs_partition; | 	struct disk_partition fs_partition; | ||||||
| 	int part = 0; | 	int part = 0; | ||||||
|  | @ -1096,8 +1117,15 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, | ||||||
| 	if (path && !file) | 	if (path && !file) | ||||||
| 		return EFI_INVALID_PARAMETER; | 		return EFI_INVALID_PARAMETER; | ||||||
| 
 | 
 | ||||||
| 	is_net = !strcmp(dev, "Net"); | 	if (!strcmp(dev, "Net")) { | ||||||
| 	if (!is_net) { | #ifdef CONFIG_NET | ||||||
|  | 		if (device) | ||||||
|  | 			*device = efi_dp_from_eth(); | ||||||
|  | #endif | ||||||
|  | 	} else if (!strcmp(dev, "Uart")) { | ||||||
|  | 		if (device) | ||||||
|  | 			*device = efi_dp_from_uart(); | ||||||
|  | 	} else { | ||||||
| 		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition, | 		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition, | ||||||
| 					       1); | 					       1); | ||||||
| 		if (part < 0 || !desc) | 		if (part < 0 || !desc) | ||||||
|  | @ -1105,11 +1133,6 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, | ||||||
| 
 | 
 | ||||||
| 		if (device) | 		if (device) | ||||||
| 			*device = efi_dp_from_part(desc, part); | 			*device = efi_dp_from_part(desc, part); | ||||||
| 	} else { |  | ||||||
| #ifdef CONFIG_NET |  | ||||||
| 		if (device) |  | ||||||
| 			*device = efi_dp_from_eth(); |  | ||||||
| #endif |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!path) | 	if (!path) | ||||||
|  | @ -1120,7 +1143,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, | ||||||
| 	s = filename; | 	s = filename; | ||||||
| 	while ((s = strchr(s, '/'))) | 	while ((s = strchr(s, '/'))) | ||||||
| 		*s++ = '\\'; | 		*s++ = '\\'; | ||||||
| 	*file = efi_dp_from_file(is_net ? NULL : desc, part, filename); | 	*file = efi_dp_from_file(desc, part, filename); | ||||||
| 
 | 
 | ||||||
| 	if (!*file) | 	if (!*file) | ||||||
| 		return EFI_INVALID_PARAMETER; | 		return EFI_INVALID_PARAMETER; | ||||||
|  |  | ||||||
|  | @ -118,6 +118,19 @@ static char *dp_msging(char *s, struct efi_device_path *dp) | ||||||
| 			     ide->logical_unit_number); | 			     ide->logical_unit_number); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  | 	case DEVICE_PATH_SUB_TYPE_MSG_UART: { | ||||||
|  | 		struct efi_device_path_uart *uart = | ||||||
|  | 			(struct efi_device_path_uart *)dp; | ||||||
|  | 		s += sprintf(s, "Uart(%lld,%d,%d,", uart->baud_rate, | ||||||
|  | 			     uart->data_bits, uart->parity); | ||||||
|  | 		switch (uart->stop_bits) { | ||||||
|  | 		case 2: | ||||||
|  | 			s += sprintf(s, "1.5)"); | ||||||
|  | 		default: | ||||||
|  | 			s += sprintf(s, "%d)", uart->stop_bits); | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
| 	case DEVICE_PATH_SUB_TYPE_MSG_USB: { | 	case DEVICE_PATH_SUB_TYPE_MSG_USB: { | ||||||
| 		struct efi_device_path_usb *udp = | 		struct efi_device_path_usb *udp = | ||||||
| 			(struct efi_device_path_usb *)dp; | 			(struct efi_device_path_usb *)dp; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue