From patchwork Tue Jul 23 18:14:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 813962 Delivered-To: patch@linaro.org Received: by 2002:adf:f288:0:b0:367:895a:4699 with SMTP id k8csp2443342wro; Tue, 23 Jul 2024 11:15:14 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUWiEDtjt1ShrbAc5XN3/q3xAZPhQFUUcg5+0m+elQQIBFtoRbSjpDNitJ2UpcTDOkcqZgBDBLmk40kF4BbeWbj X-Google-Smtp-Source: AGHT+IEsBmcvpKBcs0h717rVAKMa361QPbay/B+kT58Uor5RTVUVme4nCbkObSVt1W/IMyYb+JyV X-Received: by 2002:a50:cdd8:0:b0:58d:81ac:ea90 with SMTP id 4fb4d7f45d1cf-5a943cf6ed9mr1977599a12.38.1721758513947; Tue, 23 Jul 2024 11:15:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1721758513; cv=none; d=google.com; s=arc-20160816; b=XBmwT+uuSKaA1WICtX7ofWItBSmDO1teR/+mGfAjIDZ0nMjnpUvzX69VOWZ49FGcvw POkKAn76s6Pn2q3TWKmgkKkeuYYL7dJkgKcr1UryJeqRcZ3Zg6KLKYcZtAcJrCRWK2fG ywnTTVb3z9DxTdrmzZFtgvTgZ+uFDcm9MFObPWnlM/3JhITXZoEe1AVVp6iDlSSCS7UG qb4XTvp2yfA8lVSAsoUtdhkbCgfu0Yz9GSbSOE23Trtfz0ZSWgXVV7MLDcUVBZIrW5jT hWAyrJJwGuN6uXZYu8iL1hB+/nlzSmHEp7Y6YvHUZZHcJxpq8AblNGOELFgv0fo49Vnt iAiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=oHPYsvDXjO8Wqgk24Z47cj1cvnKaTkkeSwxtugiopmk=; fh=yDhhD7MpkefZYmYFLRa7gQP6R49dFy0zlYudy3LpojI=; b=OBxYARIifmnxdFmHzSirVKSGerVHOT6K+BjYTqYP+X84TWK8XXl/8DV9EE8ooSyMCV 0dugAXecMZERzS8KN6UImY1LuCjbnKwBIRfa+nvmomwTL/xQkFXLZdkH0iQicv2XHFoe zNKqscmn4ttiyr8FFJ+f5s99ayaHlkJovnPuALIO3y4J6IpVZ2m0+TOx/YB8Xv9PqX6c SXGtwMCGKSjeAoO33sL51IVj3cWzzs2PpYMIrMcEn+wrQQrURHL8kwazomGGZ9J2MIW6 49DxejHEfF48meTCYYZPvjncssL05SnhR4G3GUS/RrF+fr34NQeBMaBVtQvmInDI4JvI /Hqg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=upgIxGo1; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id 4fb4d7f45d1cf-5a309fffc82si6265939a12.25.2024.07.23.11.15.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jul 2024 11:15:13 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=upgIxGo1; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F060A8884D; Tue, 23 Jul 2024 20:14:52 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="upgIxGo1"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 00F208887E; Tue, 23 Jul 2024 20:14:47 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3E78088800 for ; Tue, 23 Jul 2024 20:14:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=semen.protsenko@linaro.org Received: by mail-ot1-x32e.google.com with SMTP id 46e09a7af769-70446231242so2920142a34.1 for ; Tue, 23 Jul 2024 11:14:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1721758482; x=1722363282; darn=lists.denx.de; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oHPYsvDXjO8Wqgk24Z47cj1cvnKaTkkeSwxtugiopmk=; b=upgIxGo1KYppKUUlncuJ8OPHa+Q3NrLIOBB6hEBoYfGDKwMS9+IkW3qCgGgh32zEvy 8DFFQ6s9WqMpjCJSZTZ9vP84LImJGqP39R294f9u8gm0oQu90Pyki0Rc+3x6GgLEBCY8 qOZuwJfdHFv5HE4Vp1dC+qxrwDMDPJ7Si14PpjEz5A/z2yzrh5PDCMnX1QPA4zVH7Vz1 uC2YrcCk8fiCQ5VXZlVFmHJN/K6yDXPvZOoqtjZ8M4fPoRs/axaLgsbH2AgR1pfHa9Bf 8NOz1cD8i8UPRAD0Gdp3Q48qJp3VNjm40n4IsuxW32mNMx86W6RZxK5HMll8OlkVjcrE Qcyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721758482; x=1722363282; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oHPYsvDXjO8Wqgk24Z47cj1cvnKaTkkeSwxtugiopmk=; b=sCS9z1Z4FJFqfCnYNwXu0snqU4C8JJAlpjfFaeEH8p2DUOILLZ+rHDGmdr6y97kOv7 BSJTlEonrpIF/RP8ZERyYUcMPH16Y/c8PBYkqA1JNSGs9MHSoUrFkja2Nfgk0BnUBiAt RE7syImP+AjeCsOgXXI9gLoUUluJNv6Bui6QKdH8kiCT0hnGSGcDFv+0UClqGQk/qah4 +AeGIOmhXo+JBmY8jDqB8K1feeOzxJCGyHwXRp9ItBKsHnU7U6nyZt2UU+ufXE7mYT5j DO3fmk8+09Yc3nVw28yAbYusip4cmJqqAEOwxF2P/nyBb4Y4X8gq0Tnk9raviK72radu AXKw== X-Forwarded-Encrypted: i=1; AJvYcCWTAcyuG/1QErcbm/Y62BTpuu5PaLbm+ryhMg+4xbJoqWQQUlgeP5+TZ5FMK0wrw8ZvJX/ijXLO8gWBhdieV6d4LqhhDg== X-Gm-Message-State: AOJu0YxCLsDcyCn8LB6PvKulBjqYvXtvRY/9zJ2dLY7D7H5jzhwwT7v+ YseKUYBRyLnzwh6BSPG1rcC1Ne+cQstzcSmdEcx4NgH2ly493/wR/04mwESeBRaDK23WdZUWRPM m X-Received: by 2002:a05:6830:6a8b:b0:703:68c2:3cb6 with SMTP id 46e09a7af769-709181dfe83mr4639016a34.32.1721758481949; Tue, 23 Jul 2024 11:14:41 -0700 (PDT) Received: from localhost ([136.62.192.75]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-708f6174fc9sm2103134a34.56.2024.07.23.11.14.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jul 2024 11:14:41 -0700 (PDT) From: Sam Protsenko To: Minkyu Kang , Minkyu Kang Cc: Tom Rini , Simon Glass , Lukasz Majewski , Sean Anderson , Anand Moon , Sughosh Ganu , Heinrich Schuchardt , Sumit Garg , u-boot@lists.denx.de Subject: [PATCH v3 2/5] board: samsung: e850-96: Load LDFW firmware on board init Date: Tue, 23 Jul 2024 13:14:36 -0500 Message-Id: <20240723181439.7089-3-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240723181439.7089-1-semen.protsenko@linaro.org> References: <20240723181439.7089-1-semen.protsenko@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean LDFW is a Loadable Firmware which provides additional security capabilities in EL3 monitor. For example, True Random Number Generator (TRNG) block registers can't be accessed from EL1 (where U-Boot and Linux kernel are running), but it's possible to access TRNG capabilities via corresponding SMC calls, which in turn are handled by LDFW. To do so, LDFW firmware has to be loaded first. It's stored on a raw eMMC partition, so it has to be read into NWD (Normal World) RAM buffer, and then loaded to SWD (Secure World) memory using the special SMC call to EL3 monitor program. EL3_MON will load LDFW to SWD memory, more specifically to the area starting at 0xbf700000 (with size of 7.5 MiB). That memory area is reserved in device tree, so there shouldn't be any collisions. After that LDFW becomes functional. Implement LDFW firmware loading on board init. While at it, fix the copyright date in header comments, as this board support was actually added in 2024, not in 2020: it was probably a copy-paste mistake. Signed-off-by: Sam Protsenko --- Changes in v3: - (none) Changes in v2: - (none) board/samsung/e850-96/Makefile | 4 +- board/samsung/e850-96/e850-96.c | 6 +- board/samsung/e850-96/fw.c | 131 ++++++++++++++++++++++++++++++++ board/samsung/e850-96/fw.h | 12 +++ 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 board/samsung/e850-96/fw.c create mode 100644 board/samsung/e850-96/fw.h diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile index 301c22337119..71d46ea3d2b4 100644 --- a/board/samsung/e850-96/Makefile +++ b/board/samsung/e850-96/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -# Copyright (C) 2020, Linaro Limited +# Copyright (C) 2024, Linaro Limited # Sam Protsenko -obj-y := e850-96.o +obj-y := e850-96.o fw.o diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index a00d81b5d4c3..c5cef6f19d22 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2020, Linaro Limited - * Sam Protsenko + * Copyright (c) 2024, Linaro Ltd. + * Author: Sam Protsenko */ #include +#include "fw.h" int dram_init(void) { @@ -18,5 +19,6 @@ int dram_init_banksize(void) int board_init(void) { + load_ldfw(); return 0; } diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c new file mode 100644 index 000000000000..82a0b224c670 --- /dev/null +++ b/board/samsung/e850-96/fw.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Linaro Ltd. + * Author: Sam Protsenko + * + * Firmware loading code. + */ + +#include +#include +#include "fw.h" + +#define EMMC_IFACE "mmc" +#define EMMC_DEV_NUM 0 + +/* LDFW constants */ +#define LDFW_PART_NAME "ldfw" +#define LDFW_NWD_ADDR 0x88000000 +#define LDFW_MAGIC 0x10adab1e +#define SMC_CMD_LOAD_LDFW -0x500 +#define SDM_HW_RESET_STATUS 0x1230 +#define SDM_SW_RESET_STATUS 0x1231 +#define SB_ERROR_PREFIX 0xfdaa0000 + +struct ldfw_header { + u32 magic; + u32 size; + u32 init_entry; + u32 entry_point; + u32 suspend_entry; + u32 resume_entry; + u32 start_smc_id; + u32 version; + u32 set_runtime_entry; + u32 reserved[3]; + char fw_name[16]; +}; + +static int read_fw(const char *part_name, void *buf) +{ + struct blk_desc *blk_desc; + struct disk_partition part; + unsigned long cnt; + int part_num; + + blk_desc = blk_get_dev(EMMC_IFACE, EMMC_DEV_NUM); + if (!blk_desc) { + debug("%s: Can't get eMMC device\n", __func__); + return -ENODEV; + } + + part_num = part_get_info_by_name(blk_desc, part_name, &part); + if (part_num < 0) { + debug("%s: Can't get LDWF partition\n", __func__); + return -ENOENT; + } + + cnt = blk_dread(blk_desc, part.start, part.size, buf); + if (cnt != part.size) { + debug("%s: Can't read LDFW partition\n", __func__); + return -EIO; + } + + return 0; +} + +int load_ldfw(void) +{ + const phys_addr_t addr = (phys_addr_t)LDFW_NWD_ADDR; + struct ldfw_header *hdr; + struct arm_smccc_res res; + void *buf = (void *)addr; + u64 size = 0; + int err, i; + + /* Load LDFW from the block device partition into RAM buffer */ + err = read_fw(LDFW_PART_NAME, buf); + if (err) + return err; + + /* Validate LDFW by magic number in its header */ + hdr = buf; + if (hdr->magic != LDFW_MAGIC) { + debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__); + return -EINVAL; + } + + /* Calculate actual total size of all LDFW blobs */ + for (i = 0; hdr->magic == LDFW_MAGIC; ++i) { +#ifdef DEBUG + char name[17] = { 0 }; + + strncpy(name, hdr->fw_name, 16); + debug("%s: ldfw #%d: version = 0x%x, name = %s\n", __func__, i, + hdr->version, name); +#endif + + size += (u64)hdr->size; + hdr = (struct ldfw_header *)((u64)hdr + (u64)hdr->size); + } + debug("%s: The whole size of all LDFWs: 0x%llx\n", __func__, size); + + /* Load LDFW firmware to SWD (Secure World) memory via EL3 monitor */ + arm_smccc_smc(SMC_CMD_LOAD_LDFW, addr, size, 0, 0, 0, 0, 0, &res); + err = (int)res.a0; + if (err == -1 || err == SDM_HW_RESET_STATUS) { + debug("%s: Can't load LDFW in dump_gpr state\n", __func__); + return -EIO; + } else if (err == SDM_SW_RESET_STATUS) { + debug("%s: Can't load LDFW in kernel panic (SW RESET) state\n", + __func__); + return -EIO; + } else if (err < 0 && (err & 0xffff0000) == SB_ERROR_PREFIX) { + debug("%s: LDFW signature is corrupted! ret=0x%x\n", __func__, + (u32)err); + return -EIO; + } else if (err == 0) { + debug("%s: No LDFW is inited\n", __func__); + return -EIO; + } + +#ifdef DEBUG + u32 tried = res.a0 & 0xffff; + u32 failed = (res.a0 >> 16) & 0xffff; + + debug("%s: %d/%d LDFWs have been loaded successfully\n", __func__, + tried - failed, tried); +#endif + + return 0; +} diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h new file mode 100644 index 000000000000..472664e4ed21 --- /dev/null +++ b/board/samsung/e850-96/fw.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2024 Linaro Ltd. + * Sam Protsenko + */ + +#ifndef __E850_96_FW_H +#define __E850_96_FW_H + +int load_ldfw(void); + +#endif /* __E850_96_FW_H */