From patchwork Tue Sep 22 00:21:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 53992 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by patches.linaro.org (Postfix) with ESMTPS id 7BCA522B1E for ; Tue, 22 Sep 2015 00:24:13 +0000 (UTC) Received: by wicgb1 with SMTP id gb1sf376161wic.3 for ; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:cc:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=dQA/xln2O2yQlNfuyvKmD0ppvMGrO4IWqEzMjA0S5yw=; b=LqVd5uFwpRQovvJZvCBYMETwRdlq4qYcmXWsHknAIRoBvnc89KNwy6eBO1J/bv11gd ac/w4f8E0gjHwowiS+wPgQm+FwdjRcXJpk8ipUQTtLUv91mYvh77UZ5EPCadPMLVkx63 jXe0WcDY5Lz83ICVYl0z6nWr+au5PVJj6P1qy95eAp+Kf7mAZ7pZZqXGFgW4l/hb3g28 MySElyzsY0qEecs3X4tMkaarSxg1PPKIqpt4+925dH+1H5zh2P518zgLMb3ICF/Ks+qk GkS28UdORgKJCdQzuHeHQx3Amz3UECbab8EqUhaOD0PHOzGFepepVsa/DQT1Tl5TUXei JJhw== X-Gm-Message-State: ALoCoQmIKA7+Wdxhr4/H9t0yiwBbNsCQa63UFC+eVK2oKtNRc+3JIw2BAohBJJUXmLHEpTMHL3Gb X-Received: by 10.112.158.202 with SMTP id ww10mr3793667lbb.13.1442881452739; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.205.7 with SMTP id d7ls48560lfg.82.gmail; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) X-Received: by 10.25.151.131 with SMTP id z125mr2027893lfd.104.1442881452474; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) Received: from mail-la0-f52.google.com (mail-la0-f52.google.com. [209.85.215.52]) by mx.google.com with ESMTPS id g4si17755539lam.95.2015.09.21.17.24.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Sep 2015 17:24:12 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) client-ip=209.85.215.52; Received: by lamp12 with SMTP id p12so77191808lam.0 for ; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) X-Received: by 10.152.26.98 with SMTP id k2mr8457071lag.41.1442881452348; Mon, 21 Sep 2015 17:24:12 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp178945lbq; Mon, 21 Sep 2015 17:24:11 -0700 (PDT) X-Received: by 10.180.107.195 with SMTP id he3mr16846706wib.35.1442881451430; Mon, 21 Sep 2015 17:24:11 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id ym8si34813472wjc.76.2015.09.21.17.24.11 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Sep 2015 17:24:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZeBM6-0001Tk-QP; Tue, 22 Sep 2015 00:22:46 +0000 Received: from mail-pa0-f43.google.com ([209.85.220.43]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZeBLf-0001Bp-4q for linux-arm-kernel@lists.infradead.org; Tue, 22 Sep 2015 00:22:21 +0000 Received: by pacfv12 with SMTP id fv12so133308296pac.2 for ; Mon, 21 Sep 2015 17:22:00 -0700 (PDT) X-Received: by 10.68.68.133 with SMTP id w5mr27902992pbt.143.1442881320604; Mon, 21 Sep 2015 17:22:00 -0700 (PDT) Received: from localhost.localdomain ([70.35.39.2]) by smtp.gmail.com with ESMTPSA id xv12sm26924984pac.38.2015.09.21.17.21.57 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 21 Sep 2015 17:21:59 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, leif.lindholm@linaro.org, mark.rutland@arm.com, catalin.marinas@arm.com, will.deacon@arm.com, msalter@redhat.com Subject: [PATCH v3 4/6] arm64/efi: move EFI /chosen node parsing before early FDT processing Date: Mon, 21 Sep 2015 17:21:26 -0700 Message-Id: <1442881288-13962-5-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1442881288-13962-1-git-send-email-ard.biesheuvel@linaro.org> References: <1442881288-13962-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150921_172219_382946_2314AA8C X-CRM114-Status: GOOD ( 23.79 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.220.43 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.220.43 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Cc: Ard Biesheuvel MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The early FDT processing is responsible for enumerating the DT memory nodes and installing them as memblocks. This should only be done if we are not booting via EFI, but at this point, we don't know yet if that is the case or not. So move part of the EFI init to before the early FDT processing. This involves making some changes to the way EFI discovers the locations of the EFI system table and the memory map, since those values are retrieved from the FDT as well. Instead the of_scan infrastructure, it now uses libfdt directly to access the /chosen node. Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/efi.h | 2 + arch/arm64/kernel/efi.c | 24 +++++-- arch/arm64/kernel/setup.c | 3 + drivers/firmware/efi/efi-fdt.c | 72 ++++++++------------ include/linux/efi.h | 2 +- 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index ef572206f1c3..7cc8df68c638 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -6,8 +6,10 @@ #ifdef CONFIG_EFI extern void efi_init(void); +extern void efi_parse_fdt(void *fdt); #else #define efi_init() +#define efi_parse_fdt(x) #endif #define efi_call_virt(f, ...) \ diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index ab5eeb63e2ca..a9e63122e32d 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -192,16 +192,14 @@ static __init void reserve_regions(void) if (efi_enabled(EFI_DBG)) pr_cont("\n"); } - - set_bit(EFI_MEMMAP, &efi.flags); } -void __init efi_init(void) +void __init efi_parse_fdt(void *fdt) { struct efi_fdt_params params; /* Grab UEFI information placed in FDT by stub */ - if (!efi_get_fdt_params(¶ms)) + if (!efi_get_fdt_params(fdt, ¶ms)) return; efi_system_table = params.system_table; @@ -209,16 +207,28 @@ void __init efi_init(void) memblock_reserve(params.mmap & PAGE_MASK, PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK))); memmap.phys_map = (void *)params.mmap; - memmap.map = early_memremap(params.mmap, params.mmap_size); - memmap.map_end = memmap.map + params.mmap_size; memmap.desc_size = params.desc_size; memmap.desc_version = params.desc_ver; + memmap.nr_map = params.mmap_size / params.desc_size; + + set_bit(EFI_MEMMAP, &efi.flags); +} + +void __init efi_init(void) +{ + int mmap_size = memmap.nr_map * memmap.desc_size; + + if (!efi_enabled(EFI_MEMMAP)) + return; + + memmap.map = early_memremap((u64)memmap.phys_map, mmap_size); + memmap.map_end = memmap.map + mmap_size; if (uefi_init() < 0) return; reserve_regions(); - early_memunmap(memmap.map, params.mmap_size); + early_memunmap(memmap.map, mmap_size); } static bool __init efi_virtmap_init(void) diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index f3067d4d4e35..e0ff2cca510a 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -317,6 +317,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) { void *dt_virt = fixmap_remap_fdt(dt_phys); + if (dt_virt) + efi_parse_fdt(dt_virt); + if (!dt_virt || !early_init_dt_scan(dt_virt)) { pr_crit("\n" "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n" diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c index 8f3ce66e2b02..e6622d3182ae 100644 --- a/drivers/firmware/efi/efi-fdt.c +++ b/drivers/firmware/efi/efi-fdt.c @@ -8,8 +8,7 @@ #include #include -#include -#include +#include #define UEFI_PARAM(name, prop, field) \ { \ @@ -32,60 +31,43 @@ static __initdata struct { UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) }; -struct param_info { - int found; - void *params; -}; - -static int __init fdt_find_uefi_params(unsigned long node, const char *uname, - int depth, void *data) +int __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params) { - struct param_info *info = data; const void *prop; - void *dest; - u64 val; - int i, len; + int node, i; + + pr_info("Getting EFI parameters from FDT:\n"); - if (depth != 1 || strcmp(uname, "chosen") != 0) - return 0; + node = fdt_path_offset(fdt, "/chosen"); + if (node < 0) { + pr_err("/chosen node not found!\n"); + return false; + } for (i = 0; i < ARRAY_SIZE(dt_params); i++) { - prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len); - if (!prop) - return 0; - dest = info->params + dt_params[i].offset; - info->found++; + void *dest; + int len; + u64 val; - val = of_read_number(prop, len / sizeof(u32)); + prop = fdt_getprop(fdt, node, dt_params[i].propname, &len); + if (!prop || len != dt_params[i].size) + goto not_found; + dest = (void *)params + dt_params[i].offset; if (dt_params[i].size == sizeof(u32)) - *(u32 *)dest = val; + val = *(u32 *)dest = be32_to_cpup(prop); else - *(u64 *)dest = val; + val = *(u64 *)dest = be64_to_cpup(prop); - if (efi_enabled(EFI_DBG)) - pr_info(" %s: 0x%0*llx\n", dt_params[i].name, - dt_params[i].size * 2, val); + pr_info(" %s: 0x%0*llx\n", dt_params[i].name, + dt_params[i].size * 2, val); } - return 1; -} + return true; -int __init efi_get_fdt_params(struct efi_fdt_params *params) -{ - struct param_info info; - int ret; - - pr_info("Getting EFI parameters from FDT:\n"); - - info.found = 0; - info.params = params; - - ret = of_scan_flat_dt(fdt_find_uefi_params, &info); - if (!info.found) +not_found: + if (i == 0) pr_info("UEFI not found.\n"); - else if (!ret) - pr_err("Can't find '%s' in device tree!\n", - dt_params[info.found].name); - - return ret; + else + pr_err("Can't find '%s' in device tree!\n", dt_params[i].name); + return false; } diff --git a/include/linux/efi.h b/include/linux/efi.h index 4677d8a1bfd0..4a3ab85a60d7 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -902,7 +902,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); extern void efi_get_time(struct timespec *now); extern void efi_reserve_boot_services(void); -extern int efi_get_fdt_params(struct efi_fdt_params *params); +extern int efi_get_fdt_params(void *fdt, struct efi_fdt_params *params); extern struct efi_memory_map memmap; extern struct kobject *efi_kobj;