From patchwork Wed Sep 13 22:05:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813658 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TiyeYiRn"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx1r6nzlz9sxR for ; Thu, 14 Sep 2017 08:20:32 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id B425BC2258E; Wed, 13 Sep 2017 22:10:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 77A30C22545; Wed, 13 Sep 2017 22:08:16 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id CD3A4C22616; Wed, 13 Sep 2017 22:06:16 +0000 (UTC) Received: from mail-qt0-f193.google.com (mail-qt0-f193.google.com [209.85.216.193]) by lists.denx.de (Postfix) with ESMTPS id 4606FC225A4 for ; Wed, 13 Sep 2017 22:06:13 +0000 (UTC) Received: by mail-qt0-f193.google.com with SMTP id u48so943332qtc.4 for ; Wed, 13 Sep 2017 15:06:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9wvjK6cnE3C9klIJHwS9ip4xCU9ANtGDr0esnZ4NAhQ=; b=TiyeYiRnM5KH/ISgI+j7YX+CI3qqWxcz6b17yJznxpl1NhZ9j3vRLONKthx8PRmDb2 6ceRd1rIesDwNwoyW2vBhg86KhpIeOm5B2XuUFnDqpSVqpsLYDhnf9JYAc1lwlAANO5H Ht1IPBEnFwmwJ4TYXU6hxYG31IGacvBdlQTswB0gZqX/Cd8G1AiP6Ub0nBuXUOOS6Fam KYfCQk+eVxaXIoUyUhCiW4afHKXZDxzTYeG0aULX/N56k8EsvLDwzCb+e8xdtWiHYOQQ FxPKulJjMhHFrJGxncvxz8cy/qfz+NjABAeQ1FX9sZ0bg1PRr4fqC1DPpNw4Sl7OhJyw oPMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9wvjK6cnE3C9klIJHwS9ip4xCU9ANtGDr0esnZ4NAhQ=; b=eUstutc1Fib7fLWyBCyOP7o0Eh4Nd2gs8dnbYLK2llGSAuKrkRjc4nEFOAGBrr0Tor rvF/n/mRQIj1mMRuDV/Djdo6u1D7y7yyqK/7vnfqg6BH/3UUrv1nuSiQiLZ1DLdyuwoo cJMM0zx5iFmAyI8mjlGzrA0mH169wFSWp2HRxjrjc9eWsyY2nXhW5jnYD5kIp5Paolis legHOFUzitlZnBYKSvOnxex6t/pooqxNJvNMnFQ6JS5+RUOPdFqjx71ERYYYCpnkRzqz Jw8TMlqlpSf1q9dnG1oE87QN2fX2RIakG3LqYK3eTRoVZx5DTd/13JgO7qFTN6PISjEn 2t3g== X-Gm-Message-State: AHPjjUhyVolv2Ozd6gLUgLfZFuxJBDEvRRBWjOYw7zkgovKm+vYpexAd dxRDxP1JXwdN+tKuuyM= X-Google-Smtp-Source: AOwi7QAAoNrSTCr+M80wyDhrFYyvd1NunSNCTxikgINSx5Srdy8zDBQFdlSnhP8DZuRZZ6UTrasYkg== X-Received: by 10.237.63.15 with SMTP id p15mr27677693qtf.117.1505340371941; Wed, 13 Sep 2017 15:06:11 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id 25sm10449778qtv.14.2017.09.13.15.06.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:10 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:30 -0400 Message-Id: <20170913220546.19560-8-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 07/21] efi_loader: flesh out device-path to text X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" It needs to handle more device-path node types, and also multiple levels of path hierarchy. To simplify this, initially construct utf8 string to a temporary buffer, and then allocate the real utf16 buffer that is returned. This should be mostly for debugging or at least not critical- path so an extra copy won't hurt, and is saner than the alternative. Signed-off-by: Rob Clark --- include/efi_api.h | 1 + include/efi_loader.h | 2 + lib/efi_loader/efi_device_path_to_text.c | 241 +++++++++++++++++++++++-------- 3 files changed, 181 insertions(+), 63 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index ac58fd58de..0c36122107 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -304,6 +304,7 @@ struct efi_device_path_vendor { #define EFI_PNP_ID(ID) (u32)(((ID) << 16) | 0x41D0) #define EISA_PNP_ID(ID) EFI_PNP_ID(ID) +#define EISA_PNP_NUM(ID) ((ID) >> 16) struct efi_device_path_acpi_path { struct efi_device_path dp; diff --git a/include/efi_loader.h b/include/efi_loader.h index d052b03ab7..f39c2ee6da 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -59,6 +59,8 @@ extern struct efi_simple_input_interface efi_con_in; extern const struct efi_console_control_protocol efi_console_control; extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; +uint16_t *efi_dp_str(struct efi_device_path *dp); + extern const efi_guid_t efi_guid_console_control; extern const efi_guid_t efi_guid_device_path; extern const efi_guid_t efi_guid_loaded_image; diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index f9d071ac50..1a5ef3919b 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -15,82 +15,197 @@ const efi_guid_t efi_guid_device_path_to_text_protocol = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; -static uint16_t *efi_convert_device_node_to_text( - struct efi_device_path *device_node, - bool display_only, - bool allow_shortcuts) +static char *dp_unknown(char *s, struct efi_device_path *dp) { - unsigned long buffer_size; - efi_status_t r; - uint16_t *buffer = NULL; - int i; + s += sprintf(s, "/UNKNOWN(%04x,%04x)", dp->type, dp->sub_type); + return s; +} - switch (device_node->type) { - case DEVICE_PATH_TYPE_END: - return NULL; - case DEVICE_PATH_TYPE_MESSAGING_DEVICE: - switch (device_node->sub_type) { - case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { - struct efi_device_path_mac_addr *dp = - (struct efi_device_path_mac_addr *)device_node; - - if (dp->if_type != 0 && dp->if_type != 1) - break; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - 2 * MAC_OUTPUT_LEN, - (void **)&buffer); - if (r != EFI_SUCCESS) - return NULL; - sprintf((char *)buffer, - "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", - dp->mac.addr[0], dp->mac.addr[1], - dp->mac.addr[2], dp->mac.addr[3], - dp->mac.addr[4], dp->mac.addr[5], - dp->if_type); - for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i) - buffer[i] = ((uint8_t *)buffer)[i]; +static char *dp_hardware(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_VENDOR: { + struct efi_device_path_vendor *vdp = + (struct efi_device_path_vendor *)dp; + s += sprintf(s, "/VenHw(%pUl)", &vdp->guid); + break; + } + default: + s = dp_unknown(s, dp); + break; + } + return s; +} + +static char *dp_acpi(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_ACPI_DEVICE: { + struct efi_device_path_acpi_path *adp = + (struct efi_device_path_acpi_path *)dp; + s += sprintf(s, "/Acpi(PNP%04x", EISA_PNP_NUM(adp->hid)); + if (adp->uid) + s += sprintf(s, ",%d", adp->uid); + s += sprintf(s, ")"); + break; + } + default: + s = dp_unknown(s, dp); + break; + } + return s; +} + +static char *dp_msging(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_MSG_USB: { + struct efi_device_path_usb *udp = + (struct efi_device_path_usb *)dp; + s += sprintf(s, "/Usb(0x%x,0x%x)", udp->parent_port_number, + udp->usb_interface); + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { + struct efi_device_path_mac_addr *mdp = + (struct efi_device_path_mac_addr *)dp; + + if (mdp->if_type != 0 && mdp->if_type != 1) break; - } - } + + s += sprintf(s, "/MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", + mdp->mac.addr[0], mdp->mac.addr[1], + mdp->mac.addr[2], mdp->mac.addr[3], + mdp->mac.addr[4], mdp->mac.addr[5], + mdp->if_type); + + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS: { + struct efi_device_path_usb_class *ucdp = + (struct efi_device_path_usb_class *)dp; + + s += sprintf(s, "/USBClass(%x,%x,%x,%x,%x)", + ucdp->vendor_id, ucdp->product_id, + ucdp->device_class, ucdp->device_subclass, + ucdp->device_protocol); + + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_SD: + case DEVICE_PATH_SUB_TYPE_MSG_MMC: { + const char *typename = + (dp->sub_type == DEVICE_PATH_SUB_TYPE_MSG_SD) ? + "SDCard" : "MMC"; + struct efi_device_path_sd_mmc_path *sddp = + (struct efi_device_path_sd_mmc_path *)dp; + s += sprintf(s, "/%s(Slot%u)", typename, sddp->slot_number); + break; + } + default: + s = dp_unknown(s, dp); break; - case DEVICE_PATH_TYPE_MEDIA_DEVICE: - switch (device_node->sub_type) { - case DEVICE_PATH_SUB_TYPE_FILE_PATH: { - struct efi_device_path_file_path *fp = - (struct efi_device_path_file_path *)device_node; - buffer_size = device_node->length - 4; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - buffer_size, (void **) &buffer); - if (r != EFI_SUCCESS) - return NULL; - memcpy(buffer, fp->str, buffer_size); + } + return s; +} + +static char *dp_media(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH: { + struct efi_device_path_hard_drive_path *hddp = + (struct efi_device_path_hard_drive_path *)dp; + void *sig = hddp->partition_signature; + + switch (hddp->signature_type) { + case SIG_TYPE_MBR: + s += sprintf(s, "/HD(Part%d,Sig%08x)", + hddp->partition_number, + *(uint32_t *)sig); break; + case SIG_TYPE_GUID: + s += sprintf(s, "/HD(Part%d,Sig%pUl)", + hddp->partition_number, sig); + default: + s += sprintf(s, "/HD(Part%d,MBRType=%02x,SigType=%02x)", + hddp->partition_number, hddp->partmap_type, + hddp->signature_type); } - } + + break; + } + case DEVICE_PATH_SUB_TYPE_CDROM_PATH: { + struct efi_device_path_cdrom_path *cddp = + (struct efi_device_path_cdrom_path *)dp; + s += sprintf(s, "/CDROM(0x%x)", cddp->boot_entry); + break; + } + case DEVICE_PATH_SUB_TYPE_FILE_PATH: { + struct efi_device_path_file_path *fp = + (struct efi_device_path_file_path *)dp; + int slen = (dp->length - sizeof(*dp)) / 2; + s += sprintf(s, "/%-*ls", slen, fp->str); + break; + } + default: + s = dp_unknown(s, dp); break; } + return s; +} - /* - * For all node types that we do not yet support return - * 'UNKNOWN(type,subtype)'. - */ - if (!buffer) { - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - 2 * UNKNOWN_OUTPUT_LEN, - (void **)&buffer); - if (r != EFI_SUCCESS) - return NULL; - sprintf((char *)buffer, - "UNKNOWN(%04x,%04x)", - device_node->type, - device_node->sub_type); - for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i) - buffer[i] = ((uint8_t *)buffer)[i]; +static uint16_t *efi_convert_device_node_to_text( + struct efi_device_path *dp, + bool display_only, + bool allow_shortcuts) +{ + unsigned long len; + efi_status_t r; + char buf[512]; /* this ought be be big enough for worst case */ + char *str = buf; + uint16_t *out; + + while (dp) { + switch (dp->type) { + case DEVICE_PATH_TYPE_HARDWARE_DEVICE: + str = dp_hardware(str, dp); + break; + case DEVICE_PATH_TYPE_ACPI_DEVICE: + str = dp_acpi(str, dp); + break; + case DEVICE_PATH_TYPE_MESSAGING_DEVICE: + str = dp_msging(str, dp); + break; + case DEVICE_PATH_TYPE_MEDIA_DEVICE: + str = dp_media(str, dp); + break; + default: + str = dp_unknown(str, dp); + } + + dp = efi_dp_next(dp); } - return buffer; + *str++ = '\0'; + + len = str - buf; + r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, 2 * len, (void **)&out); + if (r != EFI_SUCCESS) + return NULL; + + ascii2unicode(out, buf); + out[len - 1] = 0; + + return out; } +/* helper for debug prints.. efi_free_pool() the result. */ +uint16_t *efi_dp_str(struct efi_device_path *dp) +{ + return efi_convert_device_node_to_text(dp, true, true); +} + + static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( struct efi_device_path *device_node, bool display_only,