From patchwork Sun Sep 10 13:22:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 812149 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="KkTJEaTG"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqsNS3tLCz9s7g for ; Sun, 10 Sep 2017 23:29:28 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 5070BC21E74; Sun, 10 Sep 2017 13:25:22 +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 BBEB6C21F51; Sun, 10 Sep 2017 13:23:37 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id C3D22C21EE4; Sun, 10 Sep 2017 13:23:08 +0000 (UTC) Received: from mail-qk0-f194.google.com (mail-qk0-f194.google.com [209.85.220.194]) by lists.denx.de (Postfix) with ESMTPS id 4B0CDC21F28 for ; Sun, 10 Sep 2017 13:22:59 +0000 (UTC) Received: by mail-qk0-f194.google.com with SMTP id o77so4071065qke.2 for ; Sun, 10 Sep 2017 06:22:59 -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=PzMhEq5X4ZXskTKlDOGsIWsSXJlR83KTYQp3klUDDsQ=; b=KkTJEaTGJBuC7KJI2A5xsjpMPvY3CK6cf2qm4iyKXdTn6VuuwfzQiSCLNZ92lOYcIW vYJk2SoYHtwNP7erP+9M0TDOz5iEucs52WNUntNmdroDGNDgIMdeBQcG6B1SCtAmT9CQ xIn9jkrdpdYYOCwbiXJ6vaWWNHtVPCKoRVJpXUgK5g2vCPT8xt1bSpCVpVo+6Awd7i9A wGPhD+q/s4lgFtiggFiE8h8gS0uQ4Ef+A/zBV8RiddxX2RN9cndWJfiZnYMxPiNpywNQ qc8c1FjQyWhCqJYCZUQbsJN8pTPOiakol4GaPTZlfhLz9DYKtepoNfdJoAbr7Ac/Ya+6 bfdA== 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=PzMhEq5X4ZXskTKlDOGsIWsSXJlR83KTYQp3klUDDsQ=; b=EeM/dy0TDN21pKF/KfcGbFsSBP9oRMjfAehPj6e+dAT+AgagTTK2c6osNiqVQ3xoIq PhqTR994PRKJ9I9Fzy6CGQaiLli+OIaBaxCUkM24CUIV/zTlV+XvEnTVJCVWQHYNHAqE ZAs/NGOd0ZqmfxnpefNxs+5s7SWyz9BBomtLlHwgym5RnuF0tdIvO1QNWdLooOjDMJba 2p3MqiR+g1uouFAnJ8BUxqPjiDDPifpYrfGWmQCYqmFVDSWPEtmw3kKHrmCZna2f/g8R 7JvaxQUKeseeLPPG3VbAN+kkJxa276tpWhGjbAgS2IZoWPmf9Qsa5icEcwSuH4v0XiRx /KyQ== X-Gm-Message-State: AHPjjUjUii3fUAVLG8nkh3Kzq7IAUuZMXU/5btgyxdQm/gNaUtWsVZYC FSctlU27cL5DeIpk3v8= X-Google-Smtp-Source: AOwi7QBug7XuUQuiZNyHHL6+k5fJh1V+sfXT3y88l+nSOVx+wxc5U6zHDGWNFkRka3tRnU3OSYMdrw== X-Received: by 10.55.167.144 with SMTP id q138mr11134617qke.74.1505049777992; Sun, 10 Sep 2017 06:22:57 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id s69sm4195296qka.95.2017.09.10.06.22.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 10 Sep 2017 06:22:56 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sun, 10 Sep 2017 09:22:26 -0400 Message-Id: <20170910132236.14318-6-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170910132236.14318-1-robdclark@gmail.com> References: <20170910132236.14318-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones , Leif Lindholm Subject: [U-Boot] [PATCH v1 05/12] efi_loader: flesh out unicode protocol 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" Not complete, but enough for Shell.efi and SCT.efi. Signed-off-by: Rob Clark --- include/efi_api.h | 9 +++ include/efi_loader.h | 1 + lib/efi_loader/efi_boottime.c | 5 +- lib/efi_loader/efi_unicode.c | 143 +++++++++++++++++++++++++++++++++++------- 4 files changed, 134 insertions(+), 24 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 4853b71497..5612dfad49 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -804,6 +804,15 @@ struct efi_hii_string_protocol UINTN *secondary_languages_size); }; +/* + * Both UNICODE_COLLATION protocols seem to be the same thing, but + * advertised with two different GUID's because, why not? + */ + +#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + EFI_GUID(0x1d85cd7f, 0xf43d, 0x11d2, \ + 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) + #define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ EFI_GUID(0xa4c751fc, 0x23ae, 0x4c3e, \ 0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49) diff --git a/include/efi_loader.h b/include/efi_loader.h index 6668338d0b..4864b3ac77 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -77,6 +77,7 @@ extern const efi_guid_t efi_guid_device_path_utilities_protocol; extern const efi_guid_t efi_guid_hii_config_routing_protocol; extern const efi_guid_t efi_guid_hii_database_protocol; extern const efi_guid_t efi_guid_hii_string_protocol; +extern const efi_guid_t efi_guid_unicode_collation_protocol; extern const efi_guid_t efi_guid_unicode_collation_protocol2; extern unsigned int __efi_runtime_start, __efi_runtime_stop; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 04358e8aca..7b53570354 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -788,9 +788,12 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob obj->protocols[7].guid = &efi_guid_hii_config_routing_protocol; obj->protocols[7].protocol_interface = (void *)&efi_hii_config_routing; - obj->protocols[8].guid = &efi_guid_unicode_collation_protocol2; + obj->protocols[8].guid = &efi_guid_unicode_collation_protocol; obj->protocols[8].protocol_interface = (void *)&efi_unicode_collation; + obj->protocols[9].guid = &efi_guid_unicode_collation_protocol2; + obj->protocols[9].protocol_interface = (void *)&efi_unicode_collation; + info->file_path = file_path; info->device_handle = efi_dp_find_obj(device_path, NULL); diff --git a/lib/efi_loader/efi_unicode.c b/lib/efi_loader/efi_unicode.c index fdf1a99812..8d8edfb45a 100644 --- a/lib/efi_loader/efi_unicode.c +++ b/lib/efi_loader/efi_unicode.c @@ -7,59 +7,155 @@ */ #include +#include +#include #include +const efi_guid_t efi_guid_unicode_collation_protocol = + EFI_UNICODE_COLLATION_PROTOCOL_GUID; + const efi_guid_t efi_guid_unicode_collation_protocol2 = EFI_UNICODE_COLLATION_PROTOCOL2_GUID; -INTN stri_coll(struct efi_unicode_collation_protocol *this, - efi_string_t s1, - efi_string_t s2) +static int matchn(efi_string_t s1, unsigned n1, efi_string_t s2, unsigned n2) +{ + char u1[MAX_UTF8_PER_UTF16 * n1 + 1]; + char u2[MAX_UTF8_PER_UTF16 * n2 + 1]; + + *utf16_to_utf8((u8 *)u1, s1, n1) = '\0'; + *utf16_to_utf8((u8 *)u2, s2, n2) = '\0'; + + return strcasecmp(u1, u2); +} + +static INTN EFIAPI stri_coll(struct efi_unicode_collation_protocol *this, + efi_string_t s1, + efi_string_t s2) { EFI_ENTRY("%p, \"%ls\", \"%ls\"", this, s1, s2); - return EFI_EXIT(0); + + unsigned n1 = utf16_strlen(s1); + unsigned n2 = utf16_strlen(s2); + + return EFI_EXIT(matchn(s1, n1, s2, n2)); } -bool metai_match(struct efi_unicode_collation_protocol *this, - efi_string_t string, - efi_string_t pattern) +static bool match(efi_string_t string, efi_string_t pattern) +{ + while (true) { + uint16_t p = *pattern++; + bool matches = false; + + if (p == '\0' || *string == '\0') { + /* + * End of pattern or string, succeed if + * end of both: + */ + return *string == p; + } + + switch (p) { + case '*': + /* Match zero or more chars: */ + while (*string != '\0') { + if (match(string, pattern)) + return true; + string++; + } + return match(string, pattern); + case '?': + /* Match any one char: */ + string++; + break; + case '[': + /* Match char set, either [abc] or [a-c]: */ + + if (pattern[0] == '\0' || pattern[0] == ']') { + /* invalid pattern */ + return false; + } + + if (pattern[1] == '-') { + uint16_t lo, hi, c; + + /* range: [a-c] */ + lo = pattern[0]; + hi = pattern[2]; + + if (hi == '\0' || hi == ']' || pattern[3] != ']') { + /* invalid pattern */ + return false; + } + + c = tolower(*string); + lo = tolower(lo); + hi = tolower(hi); + + if (lo <= c && c <= hi) + matches = true; + + pattern += 4; + } else { + /* set: [abc] */ + while ((p = *pattern++) && p != ']') + if (matchn(string, 1, &p, 1)) + matches = true; + } + + if (!matches) + return false; + + string++; + break; + default: + if (matchn(string, 1, &p, 1)) + return false; + string++; + break; + } + } +} + +static bool EFIAPI metai_match(struct efi_unicode_collation_protocol *this, + efi_string_t string, + efi_string_t pattern) { EFI_ENTRY("%p, \"%ls\", \"%ls\"", this, string, pattern); - return EFI_EXIT(false); + return EFI_EXIT(match(string, pattern)); } -void str_lwr(struct efi_unicode_collation_protocol *this, - efi_string_t string) +static void EFIAPI str_lwr(struct efi_unicode_collation_protocol *this, + efi_string_t string) { EFI_ENTRY("%p, \"%ls\"", this, string); EFI_EXIT(0); return; } -void str_upr(struct efi_unicode_collation_protocol *this, - efi_string_t string) +static void EFIAPI str_upr(struct efi_unicode_collation_protocol *this, + efi_string_t string) { EFI_ENTRY("%p, \"%ls\"", this, string); EFI_EXIT(0); return; } -void fat_to_str(struct efi_unicode_collation_protocol *this, - UINTN fat_size, - uint8_t *fat, - efi_string_t string) +static void EFIAPI fat_to_str(struct efi_unicode_collation_protocol *this, + UINTN fat_size, + uint8_t *fat, + efi_string_t string) { - EFI_ENTRY("%p, %lu, \"%s\", %p", this, fat_size, fat, string); + EFI_ENTRY("%p, %zu, \"%s\", %p", this, fat_size, fat, string); EFI_EXIT(0); return; } -bool str_to_fat(struct efi_unicode_collation_protocol *this, - efi_string_t string, - UINTN fat_size, - uint8_t *fat) +static bool EFIAPI str_to_fat(struct efi_unicode_collation_protocol *this, + efi_string_t string, + UINTN fat_size, + uint8_t *fat) { - EFI_ENTRY("%p, \"%ls\", %lu, %p", this, string, fat_size, fat); + EFI_ENTRY("%p, \"%ls\", %zu, %p", this, string, fat_size, fat); return EFI_EXIT(false); } @@ -69,5 +165,6 @@ const struct efi_unicode_collation_protocol efi_unicode_collation = { .str_lwr = str_lwr, .str_upr = str_upr, .fat_to_str = fat_to_str, - .str_to_fat = str_to_fat + .str_to_fat = str_to_fat, + .supported_languages = (uint8_t *)"eng", };