From owner-svn-src-head@freebsd.org Thu Nov 7 15:39:29 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 402931B7E2D for ; Thu, 7 Nov 2019 15:39:29 +0000 (UTC) (envelope-from tsoome@me.com) Received: from pv50p00im-ztdg10021901.me.com (pv50p00im-ztdg10021901.me.com [17.58.6.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4786ym3YxGz3M5T for ; Thu, 7 Nov 2019 15:39:28 +0000 (UTC) (envelope-from tsoome@me.com) Received: from nazgul.lan (148-52-235-80.sta.estpak.ee [80.235.52.148]) by pv50p00im-ztdg10021901.me.com (Postfix) with ESMTPSA id 73DBC880DB7; Thu, 7 Nov 2019 15:39:24 +0000 (UTC) From: Toomas Soome Message-Id: <1AFEA810-CC13-444E-BF28-1C3D07CA0FC2@me.com> Mime-Version: 1.0 (Mac OS X Mail 13.0 \(3601.0.10\)) Subject: Re: svn commit: r354435 - head/stand/efi/libefi Date: Thu, 7 Nov 2019 17:39:21 +0200 In-Reply-To: Cc: Toomas Soome , src-committers , svn-src-all , svn-src-head To: Warner Losh References: <201911071117.xA7BH390010873@repo.freebsd.org> X-Mailer: Apple Mail (2.3601.0.10) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-11-07_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911070149 X-Rspamd-Queue-Id: 4786ym3YxGz3M5T X-Spamd-Bar: --- X-Spamd-Result: default: False [-3.60 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:17.58.0.0/16:c]; FREEMAIL_FROM(0.00)[me.com]; MV_CASE(0.50)[]; RCPT_COUNT_FIVE(0.00)[5]; TO_DN_ALL(0.00)[]; DKIM_TRACE(0.00)[me.com:+]; DMARC_POLICY_ALLOW(-0.50)[me.com,quarantine]; RCVD_IN_DNSWL_LOW(-0.10)[55.6.58.17.list.dnswl.org : 127.0.5.1]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; FREEMAIL_ENVFROM(0.00)[me.com]; ASN(0.00)[asn:714, ipnet:17.58.0.0/20, country:US]; MID_RHS_MATCH_FROM(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[148.52.235.80.khpj7ygk5idzvmvt5x4ziurxhy.zen.dq.spamhaus.net : 127.0.0.10]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; R_DKIM_ALLOW(-0.20)[me.com:s=1a1hai]; FROM_HAS_DN(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; IP_SCORE(0.00)[ip: (-8.62), ipnet: 17.58.0.0/20(-2.45), asn: 714(-2.52), country: US(-0.05)]; IP_SCORE_FREEMAIL(0.00)[]; DWL_DNSWL_LOW(-1.00)[me.com.dwl.dnswl.org : 127.0.5.1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Nov 2019 15:39:29 -0000 > On 7. Nov 2019, at 17:29, Warner Losh wrote: >=20 >=20 >=20 > On Thu, Nov 7, 2019 at 4:17 AM Toomas Soome > wrote: > Author: tsoome > Date: Thu Nov 7 11:17:03 2019 > New Revision: 354435 > URL: https://svnweb.freebsd.org/changeset/base/354435 = >=20 > Log: > loader: implement fallback efi_devpath_to_name() >=20 > UEFI 1.10 on macs does not seem to provide devpath to name = translation, > provide our own (limited) version, so we can get information about = commmon > devices. >=20 > We specifically deleted our own version of this function (it was wrong = in many ways too) because we thought we could require a minimum UEFI 2.0 = for full functionality... This sort of function is a total pain to = maintain. >=20 > I'd prefer the fallback was "you don't get this" rather than bloating = the code, especially for devices that we don't care about and will never = care about for booting... >=20 > Warner I can see why, but then again, try to debug such system=E2=80=A6 btw, = that particular one I debug is MacBookPro11,4 with quad core i7=E2=80=A6. = not even that old hw anyhow. I=E2=80=99d rather keep some bloat than spend 2-3 days to write code = just to get any idea what is going on in the machine=E2=80=A6 rgds, toomas > =20 > MFC after: 1 week >=20 > Modified: > head/stand/efi/libefi/devpath.c >=20 > Modified: head/stand/efi/libefi/devpath.c > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/stand/efi/libefi/devpath.c Thu Nov 7 07:21:45 2019 = (r354434) > +++ head/stand/efi/libefi/devpath.c Thu Nov 7 11:17:03 2019 = (r354435) > @@ -29,13 +29,16 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > +#include >=20 > static EFI_GUID ImageDevicePathGUID =3D > EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID; > static EFI_GUID DevicePathGUID =3D DEVICE_PATH_PROTOCOL; > static EFI_GUID DevicePathToTextGUID =3D = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; > static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *toTextProtocol; > -static EFI_GUID DevicePathFromTextGUID =3D = EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID; > +static EFI_GUID DevicePathFromTextGUID =3D > + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID; > static EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *fromTextProtocol; >=20 > EFI_DEVICE_PATH * > @@ -64,6 +67,427 @@ efi_lookup_devpath(EFI_HANDLE handle) > return (devpath); > } >=20 > +static char * > +efi_make_tail(char *suffix) > +{ > + char *tail; > + > + tail =3D NULL; > + if (suffix !=3D NULL) > + (void)asprintf(&tail, "/%s", suffix); > + else > + tail =3D strdup(""); > + return (tail); > +} > + > +typedef struct { > + EFI_DEVICE_PATH Header; > + EFI_GUID Guid; > + UINT8 VendorDefinedData[1]; > +} __packed VENDOR_DEVICE_PATH_WITH_DATA; > + > +static char * > +efi_vendor_path(const char *type, VENDOR_DEVICE_PATH *node, char = *suffix) > +{ > + uint32_t size =3D DevicePathNodeLength(&node->Header) - = sizeof(*node); > + VENDOR_DEVICE_PATH_WITH_DATA *dp =3D = (VENDOR_DEVICE_PATH_WITH_DATA *)node; > + char *name, *tail, *head; > + char *uuid; > + int rv; > + > + uuid_to_string((const uuid_t *)(void *)&node->Guid, &uuid, = &rv); > + if (rv !=3D uuid_s_ok) > + return (NULL); > + > + tail =3D efi_make_tail(suffix); > + rv =3D asprintf(&head, "%sVendor(%s)[%x:", type, uuid, size); > + free(uuid); > + if (rv < 0) > + return (NULL); > + > + if (DevicePathNodeLength(&node->Header) > sizeof(*node)) { > + for (uint32_t i =3D 0; i < size; i++) { > + rv =3D asprintf(&name, "%s%02x", head, > + dp->VendorDefinedData[i]); > + if (rv < 0) { > + free(tail); > + free(head); > + return (NULL); > + } > + free(head); > + head =3D name; > + } > + } > + > + if (asprintf(&name, "%s]%s", head, tail) < 0) > + name =3D NULL; > + free(head); > + free(tail); > + return (name); > +} > + > +static char * > +efi_hw_dev_path(EFI_DEVICE_PATH *node, char *suffix) > +{ > + uint8_t subtype =3D DevicePathSubType(node); > + char *name, *tail; > + > + tail =3D efi_make_tail(suffix); > + switch (subtype) { > + case HW_PCI_DP: > + if (asprintf(&name, "Pci(%x,%x)%s", > + ((PCI_DEVICE_PATH *)node)->Function, > + ((PCI_DEVICE_PATH *)node)->Device, tail) < 0) > + name =3D NULL; > + break; > + case HW_PCCARD_DP: > + if (asprintf(&name, "PCCARD(%x)%s", > + ((PCCARD_DEVICE_PATH *)node)->FunctionNumber, = tail) < 0) > + name =3D NULL; > + break; > + case HW_MEMMAP_DP: > + if (asprintf(&name, "MMap(%x,%" PRIx64 ",%" PRIx64 = ")%s", > + ((MEMMAP_DEVICE_PATH *)node)->MemoryType, > + ((MEMMAP_DEVICE_PATH *)node)->StartingAddress, > + ((MEMMAP_DEVICE_PATH *)node)->EndingAddress, tail) = < 0) > + name =3D NULL; > + break; > + case HW_VENDOR_DP: > + name =3D efi_vendor_path("Hardware", > + (VENDOR_DEVICE_PATH *)node, tail); > + break; > + case HW_CONTROLLER_DP: > + if (asprintf(&name, "Ctrl(%x)%s", > + ((CONTROLLER_DEVICE_PATH *)node)->Controller, = tail) < 0) > + name =3D NULL; > + break; > + default: > + if (asprintf(&name, "UnknownHW(%x)%s", subtype, tail) = < 0) > + name =3D NULL; > + break; > + } > + free(tail); > + return (name); > +} > + > +static char * > +efi_acpi_dev_path(EFI_DEVICE_PATH *node, char *suffix) > +{ > + uint8_t subtype =3D DevicePathSubType(node); > + ACPI_HID_DEVICE_PATH *acpi =3D (ACPI_HID_DEVICE_PATH *)node; > + char *name, *tail; > + > + tail =3D efi_make_tail(suffix); > + switch (subtype) { > + case ACPI_DP: > + if ((acpi->HID & PNP_EISA_ID_MASK) =3D=3D = PNP_EISA_ID_CONST) { > + switch (EISA_ID_TO_NUM (acpi->HID)) { > + case 0x0a03: > + if (asprintf(&name, "PciRoot(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + case 0x0a08: > + if (asprintf(&name, "PcieRoot(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + case 0x0604: > + if (asprintf(&name, "Floppy(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + case 0x0301: > + if (asprintf(&name, "Keyboard(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + case 0x0501: > + if (asprintf(&name, "Serial(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + case 0x0401: > + if (asprintf(&name, = "ParallelPort(%x)%s", > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + default: > + if (asprintf(&name, = "Acpi(PNP%04x,%x)%s", > + EISA_ID_TO_NUM(acpi->HID), > + acpi->UID, tail) < 0) > + name =3D NULL; > + break; > + } > + } else { > + if (asprintf(&name, "Acpi(%08x,%x)%s", > + acpi->HID, acpi->UID, tail) < 0) > + name =3D NULL; > + } > + break; > + case ACPI_EXTENDED_DP: > + default: > + if (asprintf(&name, "UnknownACPI(%x)%s", subtype, = tail) < 0) > + name =3D NULL; > + break; > + } > + free(tail); > + return (name); > +} > + > +static char * > +efi_messaging_dev_path(EFI_DEVICE_PATH *node, char *suffix) > +{ > + uint8_t subtype =3D DevicePathSubType(node); > + char *name; > + char *tail; > + > + tail =3D efi_make_tail(suffix); > + switch (subtype) { > + case MSG_ATAPI_DP: > + if (asprintf(&name, "ATA(%s,%s,%x)%s", > + ((ATAPI_DEVICE_PATH *)node)->PrimarySecondary =3D=3D= 1 ? > + "Secondary" : "Primary", > + ((ATAPI_DEVICE_PATH *)node)->SlaveMaster =3D=3D 1 = ? > + "Slave" : "Master", > + ((ATAPI_DEVICE_PATH *)node)->Lun, tail) < 0) > + name =3D NULL; > + break; > + case MSG_SCSI_DP: > + if (asprintf(&name, "SCSI(%x,%x)%s", > + ((SCSI_DEVICE_PATH *)node)->Pun, > + ((SCSI_DEVICE_PATH *)node)->Lun, tail) < 0) > + name =3D NULL; > + break; > + case MSG_FIBRECHANNEL_DP: > + if (asprintf(&name, "Fibre(%" PRIx64 ",%" PRIx64 = ")%s", > + ((FIBRECHANNEL_DEVICE_PATH *)node)->WWN, > + ((FIBRECHANNEL_DEVICE_PATH *)node)->Lun, tail) < = 0) > + name =3D NULL; > + break; > + case MSG_1394_DP: > + if (asprintf(&name, "I1394(%016" PRIx64 ")%s", > + ((F1394_DEVICE_PATH *)node)->Guid, tail) < 0) > + name =3D NULL; > + break; > + case MSG_USB_DP: > + if (asprintf(&name, "USB(%x,%x)%s", > + ((USB_DEVICE_PATH *)node)->ParentPortNumber, > + ((USB_DEVICE_PATH *)node)->InterfaceNumber, tail) = < 0) > + name =3D NULL; > + break; > + case MSG_USB_CLASS_DP: > + if (asprintf(&name, "UsbClass(%x,%x,%x,%x,%x)%s", > + ((USB_CLASS_DEVICE_PATH *)node)->VendorId, > + ((USB_CLASS_DEVICE_PATH *)node)->ProductId, > + ((USB_CLASS_DEVICE_PATH *)node)->DeviceClass, > + ((USB_CLASS_DEVICE_PATH *)node)->DeviceSubClass, > + ((USB_CLASS_DEVICE_PATH *)node)->DeviceProtocol, = tail) < 0) > + name =3D NULL; > + break; > + case MSG_MAC_ADDR_DP: > + if (asprintf(&name, = "MAC(%02x:%02x:%02x:%02x:%02x:%02x,%x)%s", > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[0], > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[1], > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[2], > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[3], > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[4], > + ((MAC_ADDR_DEVICE_PATH = *)node)->MacAddress.Addr[5], > + ((MAC_ADDR_DEVICE_PATH *)node)->IfType, tail) < 0) > + name =3D NULL; > + break; > + case MSG_VENDOR_DP: > + name =3D efi_vendor_path("Messaging", > + (VENDOR_DEVICE_PATH *)node, tail); > + break; > + case MSG_UART_DP: > + if (asprintf(&name, "UART(%" PRIu64 ",%u,%x,%x)%s", > + ((UART_DEVICE_PATH *)node)->BaudRate, > + ((UART_DEVICE_PATH *)node)->DataBits, > + ((UART_DEVICE_PATH *)node)->Parity, > + ((UART_DEVICE_PATH *)node)->StopBits, tail) < 0) > + name =3D NULL; > + break; > + case MSG_SATA_DP: > + if (asprintf(&name, "Sata(%x,%x,%x)%s", > + ((SATA_DEVICE_PATH *)node)->HBAPortNumber, > + ((SATA_DEVICE_PATH = *)node)->PortMultiplierPortNumber, > + ((SATA_DEVICE_PATH *)node)->Lun, tail) < 0) > + name =3D NULL; > + break; > + default: > + if (asprintf(&name, "UnknownMessaging(%x)%s", > + subtype, tail) < 0) > + name =3D NULL; > + break; > + } > + free(tail); > + return (name); > +} > + > +static char * > +efi_media_dev_path(EFI_DEVICE_PATH *node, char *suffix) > +{ > + uint8_t subtype =3D DevicePathSubType(node); > + HARDDRIVE_DEVICE_PATH *hd; > + char *name; > + char *str; > + char *tail; > + int rv; > + > + tail =3D efi_make_tail(suffix); > + name =3D NULL; > + switch (subtype) { > + case MEDIA_HARDDRIVE_DP: > + hd =3D (HARDDRIVE_DEVICE_PATH *)node; > + switch (hd->SignatureType) { > + case SIGNATURE_TYPE_MBR: > + if (asprintf(&name, "HD(%d,MBR,%08x,%" PRIx64 > + ",%" PRIx64 ")%s", > + hd->PartitionNumber, > + *((uint32_t = *)(uintptr_t)&hd->Signature[0]), > + hd->PartitionStart, > + hd->PartitionSize, tail) < 0) > + name =3D NULL; > + break; > + case SIGNATURE_TYPE_GUID: > + name =3D NULL; > + uuid_to_string((const uuid_t *)(void *) > + &hd->Signature[0], &str, &rv); > + if (rv !=3D uuid_s_ok) > + break; > + rv =3D asprintf(&name, "HD(%d,GPT,%s,%" PRIx64 = ",%" > + PRIx64 ")%s", > + hd->PartitionNumber, str, > + hd->PartitionStart, hd->PartitionSize, = tail); > + free(str); > + break; > + default: > + if (asprintf(&name, "HD(%d,%d,0)%s", > + hd->PartitionNumber, > + hd->SignatureType, tail) < 0) { > + name =3D NULL; > + } > + break; > + } > + break; > + case MEDIA_CDROM_DP: > + if (asprintf(&name, "CD(%x,%" PRIx64 ",%" PRIx64 = ")%s", > + ((CDROM_DEVICE_PATH *)node)->BootEntry, > + ((CDROM_DEVICE_PATH *)node)->PartitionStart, > + ((CDROM_DEVICE_PATH *)node)->PartitionSize, tail) = < 0) { > + name =3D NULL; > + } > + break; > + case MEDIA_VENDOR_DP: > + name =3D efi_vendor_path("Media", > + (VENDOR_DEVICE_PATH *)node, tail); > + break; > + case MEDIA_FILEPATH_DP: > + name =3D NULL; > + str =3D NULL; > + if (ucs2_to_utf8(((FILEPATH_DEVICE_PATH = *)node)->PathName, > + &str) =3D=3D 0) { > + (void)asprintf(&name, "%s%s", str, tail); > + free(str); > + } > + break; > + case MEDIA_PROTOCOL_DP: > + name =3D NULL; > + uuid_to_string((const uuid_t *)(void *) > + &((MEDIA_PROTOCOL_DEVICE_PATH *)node)->Protocol, > + &str, &rv); > + if (rv !=3D uuid_s_ok) > + break; > + rv =3D asprintf(&name, "Protocol(%s)%s", str, tail); > + free(str); > + break; > + default: > + if (asprintf(&name, "UnknownMedia(%x)%s", > + subtype, tail) < 0) > + name =3D NULL; > + } > + free(tail); > + return (name); > +} > + > +static char * > +efi_translate_devpath(EFI_DEVICE_PATH *devpath) > +{ > + EFI_DEVICE_PATH *dp =3D NextDevicePathNode(devpath); > + char *name, *ptr; > + uint8_t type; > + > + if (!IsDevicePathEnd(devpath)) > + name =3D efi_translate_devpath(dp); > + else > + return (NULL); > + > + ptr =3D NULL; > + type =3D DevicePathType(devpath); > + switch (type) { > + case HARDWARE_DEVICE_PATH: > + ptr =3D efi_hw_dev_path(devpath, name); > + break; > + case ACPI_DEVICE_PATH: > + ptr =3D efi_acpi_dev_path(devpath, name); > + break; > + case MESSAGING_DEVICE_PATH: > + ptr =3D efi_messaging_dev_path(devpath, name); > + break; > + case MEDIA_DEVICE_PATH: > + ptr =3D efi_media_dev_path(devpath, name); > + break; > + case BBS_DEVICE_PATH: > + default: > + if (asprintf(&ptr, "UnknownPath(%x)%s", type, > + name? name : "") < 0) > + ptr =3D NULL; > + break; > + } > + > + if (ptr !=3D NULL) { > + free(name); > + name =3D ptr; > + } > + return (name); > +} > + > +static CHAR16 * > +efi_devpath_to_name(EFI_DEVICE_PATH *devpath) > +{ > + char *name =3D NULL; > + CHAR16 *ptr =3D NULL; > + size_t len; > + int rv; > + > + name =3D efi_translate_devpath(devpath); > + if (name =3D=3D NULL) > + return (NULL); > + > + /* > + * We need to return memory from AllocatePool, so it can be = freed > + * with FreePool() in efi_free_devpath_name(). > + */ > + rv =3D utf8_to_ucs2(name, &ptr, &len); > + free(name); > + if (rv =3D=3D 0) { > + CHAR16 *out =3D NULL; > + EFI_STATUS status; > + > + status =3D BS->AllocatePool(EfiLoaderData, len, (void = **)&out); > + if (EFI_ERROR(status)) { > + free(ptr); > + return (out); > + } > + memcpy(out, ptr, len); > + free(ptr); > + ptr =3D out; > + } > + =20 > + return (ptr); > +} > + > CHAR16 * > efi_devpath_name(EFI_DEVICE_PATH *devpath) > { > @@ -78,7 +502,7 @@ efi_devpath_name(EFI_DEVICE_PATH *devpath) > toTextProtocol =3D NULL; > } > if (toTextProtocol =3D=3D NULL) > - return (NULL); > + return (efi_devpath_to_name(devpath)); >=20 > return (toTextProtocol->ConvertDevicePathToText(devpath, TRUE, = TRUE)); > } > @@ -86,8 +510,8 @@ efi_devpath_name(EFI_DEVICE_PATH *devpath) > void > efi_free_devpath_name(CHAR16 *text) > { > - > - BS->FreePool(text); > + if (text !=3D NULL) > + BS->FreePool(text); > } >=20 > EFI_DEVICE_PATH *