From patchwork Tue Sep 1 02:22:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zong Li X-Patchwork-Id: 2295572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=QSj5vIuV; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=UmnaYcoj; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hYqPy6RS2z1xv2 for ; Tue, 01 Sep 2026 12:22:30 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Jtk6UmVyPC7AkNQgO/Db9mDz1wENY2ryLbP3GlSusSk=; b=QSj5vIuVKf5TRy F6aIo0JvGos+PZzSPoVS/DkvUvE8jIp1t0pJ+Vq3JugJQk0+1crYFkv6iffVSS2RYgiDoadMAcs10 5kVh8W6i/nUbyVdsvS78V4RdOx3s19i1lV0/19UdPD45NpLKaGwOmr45VgxRdezSLvGZyVsTjNxdS ND7pn4xWbZDcKuzlJY6M2dArgU5Iv1E/G4699UBHw1nczrjOB3ebvjWuyMEV1cirOQ3wvY253Lmy5 CQ9V5ixkLskSUm5IXPokKlVcsyJ/klAarwC8hwQwbAss584Mu+oka9GOVJ8SYzkxCPRkR1mIQuQrB j7SwRAUslu77ZU99/nlw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8i-0000000ArgO-1MEz; Tue, 01 Sep 2026 02:22:20 +0000 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8g-0000000Arf2-0CSG for opensbi@lists.infradead.org; Tue, 01 Sep 2026 02:22:19 +0000 Received: by mail-pg1-x536.google.com with SMTP id 41be03b00d2f7-c9d1fff21edso3720531a12.1 for ; Mon, 31 Aug 2026 19:22:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1788229337; x=1788834137; darn=lists.infradead.org; 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:content-type; bh=6YrRK2bruEL8IcLW0TtPEHFHsBSp6hl8Y6iUCzFtdy4=; b=UmnaYcojmj30N0G+Hypcrss4ERep97P1yMyJj/7uqwLT9FptlpFSpyatEDkpVgiciK EHfuOWrghZ9n//F1VGaDDWa0mV89UmrbpzeC3BUM1r01E//NNkvEAkEV2D2h8hx6n7Wc C6fjJmP77G+rlCkQiYoY/lBOBlcEuWRQNJspRmtZabt0q8nBbWBJ1KB1wkL7MSYwNdNo sB9QQByRB8qagL26EmrzBD1bDMHdQkjPSkzM5goCPxZEB/v6CqvDNBWto1b3epN4+fIJ 9l6Ml7HkJL6A1UBWANcm+I5jUxxCM2kn7iMxr9w05YTnMmM5LG8SRzFzWo6rC8DfMX5+ o3zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788229337; x=1788834137; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=6YrRK2bruEL8IcLW0TtPEHFHsBSp6hl8Y6iUCzFtdy4=; b=aJjXOKB58R493wuExjJlnpCemFDJbGYbmzlxiDfVqxVppgMA7J0upzQ84pPQrNS9Vw AXybiDovFwx7WNP7ae8557Rs8kIbc3E2YEaEylDGC2ZliPx9QRER3p2V30CfgIRyfw1a MlC/zT/zyjbMmkfCfVB2ccQbTlGhZZUME/XN2HyHz7dARirCoMRivBMJy9Shnchijl0U JrnpQ6zqGz9xe3ZnzixvD0uB8J5OxYpF+7vimCSv68FnFTwAq61JXQNgS6kvTCQkbqBS N89OJJ7KTLwU3iPOYhaR2/U1S5O+yY3w6CVRSGEkAYgV6mbagn7Ezf/zmOoAxgCFLVKh kaGw== X-Gm-Message-State: AFuF++no5kvfVYQxVqYb0fyQNAAycAoPHjXknH2o6J1ZJVb5hN0iRkS4 Ili4uOeXYPTTNSt1oEgSliwri6VrKO7FbBqAzYN443bKeLjkfT052GlpGK+Fnvwg/8/93cEMCQ7 WbAxoMAE+2uwgb3VmZT2Qh1SIV3QHmVUiLZoQCYLbphzr+/eEcijYTo3/wUJd619+y/zqsojV8K Odt8nd2SbMkZ5Hjj6Sca6wwUgY5uPFGaB2ekIMAVKOghvA5g== X-Gm-Gg: AYBFou3QaCUKVl52sJ+8hNvsprkhtefG8xlTo5CPGUcti9qO5IsCVXOr0gZOlpK9TCG tIchhTnXo9U209LGYoeqnB8uvJnT7Lxd42wUGasUZdqBV1pxxY65LH8qay7ZU9InfBpCOf1kARl zCcoTqa+0gurRgWlhi+2TO/IqAVw2tgvfggvKOlZGcW+FPtRNzwHcGm8f0BltuY9D/L6LtLPTfI MNkFd7x67dvOlS1eyCeqEi0w96ySYrDfN8BuNIGKKIfZq2YI2jQtiCAy4P+XiL5zvZrktDhKIWo INjp5ut6MYXVntIC2QSKb8uvORH1vSli65UpqMQ7S8qtqmXloTajjM7d/7b30LZ8wEQTPe9pHzY 3nb+KLeuqtnMuYNmC/dAh7I4rpr3tdAAVKf03mfKrjNERU1isNFm8QprjLeLdOKY+j2c72u6Qqj luG5dmsFBRuBM8Kvyr9y7A3c0Bcks7pXwmGnERwdoklje69LDxVHJusUyWi8rwLMyypfSnQkdX X-Received: by 2002:a17:90b:37d0:b0:395:4290:46e0 with SMTP id 98e67ed59e1d1-39907b66052mr7158009a91.5.1788229336703; Mon, 31 Aug 2026 19:22:16 -0700 (PDT) Received: from sw04.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e0d3fdf6sm33287164c88.6.2026.08.31.19.22.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:22:16 -0700 (PDT) From: Zong Li To: opensbi@lists.infradead.org, anup@brainfault.org Cc: Zong Li Subject: [PATCH 1/3] firmware: fw_base.S: add a formatted OpenSBI firmware header Date: Mon, 31 Aug 2026 19:22:09 -0700 Message-ID: <20260901022211.2619560-2-zong.li@sifive.com> X-Mailer: git-send-email @GIT_VERSION@ In-Reply-To: <20260901022211.2619560-1-zong.li@sifive.com> References: <20260901022211.2619560-1-zong.li@sifive.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260831_192218_104682_2CC083B3 X-CRM114-Status: GOOD ( 17.29 ) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Add a fixed 128-byte header at the very beginning of every OpenSBI firmware image, regardless of the firmware type. The header lets the previous booting stage identify an OpenSBI image and, more impor [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:536 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add a fixed 128-byte header at the very beginning of every OpenSBI firmware image, regardless of the firmware type. The header lets the previous booting stage identify an OpenSBI image and, more importantly, gives it a well-known place inside the image to hand over information to OpenSBI by patching a few words instead of setting up registers. This first patch only introduces the layout: - a 4-byte jump over the header to _start_real, so that _start stays the entry point of the image. The jump is assembled with '.option norvc' so that the fields behind it are always at a fixed offset, even for a build with compressed instructions enabled, - the 'OSBI' magic, a header version, the XLEN the firmware was built for and the size of the firmware image, so that the previous booting stage can validate the image and figure out how much memory it occupies, - a flags word and three 8-byte override values, which are unused (and zero) for now and are wired up by the next patch. The layout is deliberately identical for RV32 and RV64 so that the previous booting stage can parse the header without knowing the XLEN of the firmware upfront. Each override value is followed by a reserved 8-byte slot so that the same layout can be extended to RV128 later. Suggested-by: Anup Patel Signed-off-by: Zong Li --- firmware/fw_base.S | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/firmware/fw_base.S b/firmware/fw_base.S index 0c5c65c1..dd2adb8a 100644 --- a/firmware/fw_base.S +++ b/firmware/fw_base.S @@ -17,6 +17,15 @@ #define BOOT_LOTTERY_ACQUIRED 1 #define BOOT_STATUS_BOOT_HART_DONE 1 +/* OpenSBI firmware header */ +#define FW_HEADER_MAGIC_VALUE 0x4942534f /* ASCII string "OSBI" */ +#define FW_HEADER_VERSION 0x1 +#define FW_HEADER_SIZE 128 +#define FW_HEADER_RESERVED_OFFSET 0x48 +#define FW_HEADER_FLAGS_OVERRIDE_A0 (1 << 0) +#define FW_HEADER_FLAGS_OVERRIDE_A1 (1 << 1) +#define FW_HEADER_FLAGS_OVERRIDE_A2 (1 << 2) + .macro MOV_3R __d0, __s0, __d1, __s1, __d2, __s2 add \__d0, \__s0, zero add \__d1, \__s1, zero @@ -44,8 +53,67 @@ .section .entry, "ax", %progbits .align 3 .globl _start + .globl _start_real .globl _start_warm _start: + /* + * OpenSBI firmware header + * + * Every OpenSBI firmware image starts with this fixed 128-byte + * header. The layout is identical for RV32 and RV64 (and can be + * extended for RV128 by using the reserved half of each override + * field), so the previous booting stage can parse the header without + * knowing the XLEN of the firmware upfront. + * + * Offset Size Field + * 0x00 4 jump to _start_real + * 0x04 4 magic ('OSBI') + * 0x08 4 header version + * 0x0c 4 firmware XLEN + * 0x10 4 firmware size (_fw_end - _fw_start) + * 0x14 4 flags (FW_HEADER_FLAGS_*) + * 0x18 8 override value for a0 + * 0x20 8 reserved (upper half of the a0 value on RV128) + * 0x28 8 override value for a1 + * 0x30 8 reserved (upper half of the a1 value on RV128) + * 0x38 8 override value for a2 + * 0x40 8 reserved (upper half of the a2 value on RV128) + * 0x48 56 reserved + */ +_fw_header_jump: + /* + * Must stay a 4-byte instruction so that the fields below are always + * at a fixed offset. 'norvc' keeps the assembler from picking c.j and + * 'norelax' keeps the linker from compressing it later on, which it + * would otherwise happily do for a jump this short. + */ + .option push + .option norvc + .option norelax + j _start_real + .option pop +_fw_header_magic: + .word FW_HEADER_MAGIC_VALUE +_fw_header_version: + .word FW_HEADER_VERSION +_fw_header_xlen: + .word __riscv_xlen +_fw_header_size: + .word (_fw_end - _fw_start) +_fw_header_flags: + .word 0 +_fw_header_override_a0: + .dword 0 + .dword 0 /* reserved */ +_fw_header_override_a1: + .dword 0 + .dword 0 /* reserved */ +_fw_header_override_a2: + .dword 0 + .dword 0 /* reserved */ + /* Reserved, pads the header up to FW_HEADER_SIZE bytes */ + .fill (FW_HEADER_SIZE - FW_HEADER_RESERVED_OFFSET), 1, 0 +_start_real: /* Find preferred boot HART id */ MOV_3R s0, a0, s1, a1, s2, a2 call fw_boot_hart From patchwork Tue Sep 1 02:22:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zong Li X-Patchwork-Id: 2295569 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=ZavWcfjp; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=ZVkR1bgc; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hYqPx19bKz1xv2 for ; Tue, 01 Sep 2026 12:22:29 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=rJXPIzVbsCAzJO60p00uykzenWoqXhQXAv0IL2L8EIg=; b=ZavWcfjpIOP2Ww jqs4CRjo0Wv6pBcnSh6x0WFYw0A9fFJsFLgftAEtZKvnDI9B3Ld6Lcvi94QCEcUhydh404POUBKOK VskWF34fOvriOeS4i6941JFV5bUnu7CJ9heYV6n9EGCMc7HHb1XhmO2PC0U8TsaK2zeF6u42yozVv VteVttBpAJ38TzY0oZhYUV4FC9g4X7xWiiG8++jEZxSmzwUW62FqagHYLRC8+GlzU02zC359CiWfL HcNoFN+ETtakDO9sj4KN4NQPVj1G8aCg8ehM2iRrfYYRSAI0t+CWB7Y945ad/gaQRoM3SQNhNIYiD m1y+mYKtWfzXYSe9iAPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8j-0000000Argq-1xcH; Tue, 01 Sep 2026 02:22:21 +0000 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8g-0000000ArfH-21sV for opensbi@lists.infradead.org; Tue, 01 Sep 2026 02:22:20 +0000 Received: by mail-pg1-x530.google.com with SMTP id 41be03b00d2f7-cc1cc97b84bso3752122a12.1 for ; Mon, 31 Aug 2026 19:22:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1788229338; x=1788834138; darn=lists.infradead.org; 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:content-type; bh=ytSKm5C2E+jtd+CbfUMGPTc+Q0I8tzsCT3mOTe4cLIw=; b=ZVkR1bgcFQr0UDKShRANEqqxJTPQZjbQzY0zogHds9QMWeuqxoLvAMSKCg6t5Gt02r P+otxPSfqAdjwpvQxzLsbhLFI37HcyLeXIBPkFtXhPgb7LAh+ekwbglV7VYFdJUXWHf9 /98YNdF4TfsNCJAGsJSWvx0o7uPNqIUC3V6Q8p4iw9ES8fjxpsd16KdZD5fKrrHx43M7 b0aJr+hf47kRAz1lbusf5bxjTL4iW0jjM0RYbtm//3C5yAY1Bwv+CU6FyXmQdmCoy9+2 y0tLWZ7XYfoFySvLsq0+DJg/a9UDK2LxqBMs2ImrxiyAFoe2yLi0+wyfqvntBOGqsCzg Z1Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788229338; x=1788834138; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ytSKm5C2E+jtd+CbfUMGPTc+Q0I8tzsCT3mOTe4cLIw=; b=DSECPqlFAWXfNJ+FJK2709Bsmy6T7tCs+04DenLQr/ClPCdbdif5AJpFIffBstplAb u1T5GkNiWU6+7D6U/A+i6nrA+39HAqoo/N/wjkM3EPjUN26jkH0/1fl3SrFWmJuawi9g tUtIl8qyguy3Gcz1+LtodPPrS7ApxTuP/7ki77EL233acPlNe/sACkt2D3ybOTX1ldr3 RuaeCx6LR1+dd20Nd7gnOPTvz+4SKtRnT4/J1Saud1jLkI85bYRrofLYAT2Fwos6ak4B de7PQepKiifKXYDR6qcezH4rwldHAyJRMRpc3275Mc8PQqbmJqTYHWQNqe9PEGHpYbna +6hQ== X-Gm-Message-State: AFuF++lyd877XmfsN/ZH2RoRXbd6VDif/8Xc58PqvpIg0J3xPoFr/9Ny NQDSq0p+TxW74PPi3SEL5RufGsqPpovNk+AHYGaqvn0MSAA9wiBGamQZtmOjOpFlhip39Ktf0qb hrC5NgHigVePbHIMReJvNyifl0/RxnhmD8V/ye9FTYKvMJ3gZ8L2U3YIpm4E8E86cCopi2DhzXN G7g7KHKJ7fxAXO6W/J2fT2rY13hTJKq+vX4ly7cZXI4I+0Jg== X-Gm-Gg: AYBFou3FPZLUWrKw0X/ysKVwgzkUS8t0jldVA4FPN1sSaXzEA8ITzeIe3TMaAxvtR7P qR+XNqY/a6gk54GUD8zgwPnVs20XWCvIEx5fD6JkYHSFzD5VdrBzg758EsCu/ACtW63I4FSuo3e pqtDRSzkpkV2cl6oy/KwoVAwTMrj87xZX3JPGp2+/dYWppTjdzRtuF78BogkneP7Xyx8frkeWXP 3cIDwWA6F+atbLWaalXtUQp/8bmn/BGN5RUeCBpoNqkqu1ajr15EU3I9cIJHxVsj2cvddL6Xtuy Ut4jmoqHSnz/VP7RvzAQO+xIwzWb+twepr3RopDfk+3KQF/7yibmxGCYg9YAuqvFHh2WXXJW3vK liLsk91ooQYRtr4buSYoB6/SmLjaIhRt5SBl0iUaPk7O0g7QLpWrD/CTCX1itLadaHtbfo/iRor og1Af5FqeU6mesZ7VMMA3lL5RS/UeLDITBLA+A5bIqXN2T2TpP8MA7Putm1dlGfuyf9bpIydbo X-Received: by 2002:a17:90b:4e88:b0:398:a145:5d3d with SMTP id 98e67ed59e1d1-39907b17a4dmr7308075a91.6.1788229337736; Mon, 31 Aug 2026 19:22:17 -0700 (PDT) Received: from sw04.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e0d3fdf6sm33287164c88.6.2026.08.31.19.22.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:22:17 -0700 (PDT) From: Zong Li To: opensbi@lists.infradead.org, anup@brainfault.org Cc: Zong Li Subject: [PATCH 2/3] firmware: fw_base.S: override a0, a1 and a2 from the firmware header Date: Mon, 31 Aug 2026 19:22:10 -0700 Message-ID: <20260901022211.2619560-3-zong.li@sifive.com> X-Mailer: git-send-email @GIT_VERSION@ In-Reply-To: <20260901022211.2619560-1-zong.li@sifive.com> References: <20260901022211.2619560-1-zong.li@sifive.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260831_192218_522465_7A843F74 X-CRM114-Status: GOOD ( 16.66 ) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Wire up the flags word and the three override values in the OpenSBI firmware header. When the previous booting stage sets one of the FW_HEADER_FLAGS_OVERRIDE_A[012] bits, the cold boot path replaces t [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:530 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Wire up the flags word and the three override values in the OpenSBI firmware header. When the previous booting stage sets one of the FW_HEADER_FLAGS_OVERRIDE_A[012] bits, the cold boot path replaces the matching register with the value stored in the header before doing anything else with the boot arguments. This lets a previous booting stage which cannot pass the boot arguments in registers hand them over by patching a few words in the firmware image instead. For example, a booting stage running on a dedicated boot processor can load the OpenSBI image, patch the header with the hart id, the DTB address and, for FW_DYNAMIC, the address of a struct fw_dynamic_info it built somewhere in DRAM, and then release the hart that runs OpenSBI, without ever being able to set up that hart's registers itself. The flags word is zero in a freshly built image, so nothing is overridden and every existing booting stage keeps passing a0, a1 and a2 in registers as before. Suggested-by: Anup Patel Signed-off-by: Zong Li --- firmware/fw_base.S | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/firmware/fw_base.S b/firmware/fw_base.S index dd2adb8a..bf458ba0 100644 --- a/firmware/fw_base.S +++ b/firmware/fw_base.S @@ -114,6 +114,38 @@ _fw_header_override_a2: /* Reserved, pads the header up to FW_HEADER_SIZE bytes */ .fill (FW_HEADER_SIZE - FW_HEADER_RESERVED_OFFSET), 1, 0 _start_real: + /* + * Override a0, a1 and a2 with the values from the firmware header. + * + * This is for a previous booting stage which cannot pass the boot + * arguments in registers, but can patch the firmware image before + * jumping to it. Nothing is overridden when the previous booting + * stage left the flags word alone, so the registers passed by all + * existing booting stages are used as-is. + * + * This runs before relocation, so only PC-relative addressing is + * used. t0, t1 and t2 are free to use here: the boot arguments live + * in a0-a4 and every other register is reset further down the cold + * boot path. + */ + lla t0, _fw_header_flags + lw t0, (t0) + andi t1, t0, FW_HEADER_FLAGS_OVERRIDE_A0 + beqz t1, _skip_override_a0 + lla t2, _fw_header_override_a0 + REG_L a0, (t2) +_skip_override_a0: + andi t1, t0, FW_HEADER_FLAGS_OVERRIDE_A1 + beqz t1, _skip_override_a1 + lla t2, _fw_header_override_a1 + REG_L a1, (t2) +_skip_override_a1: + andi t1, t0, FW_HEADER_FLAGS_OVERRIDE_A2 + beqz t1, _skip_override_a2 + lla t2, _fw_header_override_a2 + REG_L a2, (t2) +_skip_override_a2: + /* Find preferred boot HART id */ MOV_3R s0, a0, s1, a1, s2, a2 call fw_boot_hart From patchwork Tue Sep 1 02:22:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zong Li X-Patchwork-Id: 2295571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=C/yfmrij; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=ZswccM8C; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hYqPx6869z1xyG for ; Tue, 01 Sep 2026 12:22:29 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kAvF8M/xjTyddHDBU+DBEgvqgzSCUApFUXliL41FgZk=; b=C/yfmrije8ToDo VYoFSHJRNo9mIMoAv9hAemgviUdfVqTRhtviBzx424+1oPGBMUnPRAAmss1B4qU0jnYa+MuwQLVcc wEknHG4eGxjmk7NgqkYvrNhx4m1JYkfUoyF1mCojOutz7zwI8DAMVIUiwrdUIPlJ/TLjh1z/H3hr6 U7SZdYgPYhiQYihpUUZkB6xS2DD/jGYO0ISppkM6WRL4iI4rPszG9DOH2P66JESh3wMN/dcLkKpye /Kb2d156Z4Ey7Gw2nY6TxMBrWV9mI84prAkOx8GV45jdXCV+LdXSzOJ9uG39ODagcmCEcH6eNqm8H 7J2kpwfSpLofa+i1S6fg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8k-0000000ArhE-2L94; Tue, 01 Sep 2026 02:22:22 +0000 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1E8h-0000000Arfs-3emX for opensbi@lists.infradead.org; Tue, 01 Sep 2026 02:22:21 +0000 Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-38dfe7eb825so448612a91.0 for ; Mon, 31 Aug 2026 19:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1788229339; x=1788834139; darn=lists.infradead.org; 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:content-type; bh=OkDHAAfq6OdlCHHpeeeZ8m2vmdS3+JGiEr7G7wcJYO8=; b=ZswccM8CQGOnn2EHPJhdFYeaqptgO8v0ubDZaAkAPla+tHUwpOTViDE22R2UIKfIri JN7USl2IFQyhCopneDJUIAzrTVPjkmxBSFcVGTOOfFR7tMTba6zhX+D9rpEM9NBt6+fq roQD86HmtQwgCuOQY3FAyCB6mjx4+vHRVAT26MeKBEn3nkOciWOW1hfkeHmt+S5dVAhL H1HeRB6CyiY5xhpBvGIPUZWPxZ6S+KHYebVjd5HmkyHNN6nv7oMgRPNH9ppKGm1tXfxY O2w5bimxf7wYivRfj8loId4znv9f/EjFA7ERED70ZTHNhQXZoEJfQnT0PENKFrKgvAai JHnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788229339; x=1788834139; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OkDHAAfq6OdlCHHpeeeZ8m2vmdS3+JGiEr7G7wcJYO8=; b=Tua0e2PLBZLD22m3NksWMAJQ5cSh0RWlORLVx/lqAshuDx6GwGWX+zXHpy/sNKndsd BFEVOAblaB7vGq94Qso38/gkrdELLVnwHenJGgc97e6igXWUauE8rldgZps7OkaSxMhs MLdoP9RDwjiIQkO/lxvxYAnGnp1KSD6mThhA8zxmNqrSaWtf2lKI0OVKYSxITmDZtGdt ph1tETF39903N4UcpM4jbPgsihXJ+2xlCoR2PXPgAa+pFnsgqQSf++/3jkU6yMF+NnUi 2EM+mO5E1VxJBw6uEkLqetO3NBXenqcYfeXzVJAFZ/LTaRP82eJcxV189kzuvQp8RowO 3x/A== X-Gm-Message-State: AFuF++kRrhL0r5cnRPv0cjn6hAMdyqO5nHBPwQCuSyFrt+3dKiFtqNOM Cgi23Lx0GEqVBYBNK7W7QD9Hkjq+iayeed/yTAqHejNmkUn/KoNJL0gQCElbrot0MtWFiKjNHqs exrn8BOM4+LpMdsB63EhvQX5rYV1NZerNDfpgDfOkCyh4lyhhuwOqrSRTkas5Tks8YXUPbO04il BJBRVypJUHvqj8JLR53HiK4yEnN8OiMK81UegOBsaCWCrWSfBP X-Gm-Gg: AYBFou30jZkLOnVkOR7acnbQ7uibWAzEFzBSvVlz2V3oUkzzVtB/K02Yn6aRjTpNDTM fhAuNb6p5yirTTPKFGQcXCGJEWzYn1gtUt9J9ErrDioXpQ4adWqgxUxUa24gHVcNAqtPTDCDht+ 1zFhkzaIaAbZsRusvb9SmoRzLXw4VNcqcPZ9zs5iDXeYBGKkpcVQhfQRX1CWpeGdNUd0OVtj1XU 0oRMpnmx+kggZnB7bSrXOVWdPASDerl1HJ2CcYjdTGI0t3mUbPMxKaemI4VCUWr6HravUvyuFJr Xt8MIZI1DPF4FwNsQ++SScQxe8WviZOJWePwaIPQP5g7qSSOfOTH7PCtbCgW2eOL5wzElyQvDQ0 cc3f6hkM3kL+ADI0B2e0ajnZr79A80hX9svLagh3ZlJS7UCfintt4wbOXcwPySyG50/JOxpcHFT 7zaCv/kntce/VZXHaiJXUgtl9pH9zfM7VTyVmd+ijCS8uR74K2nNnWMcA9cuWkuESGsw7dVEuwj w8cX3otxuw= X-Received: by 2002:a17:90b:1dce:b0:38e:5b59:c2ff with SMTP id 98e67ed59e1d1-396d0ea8b47mr46686545a91.3.1788229338562; Mon, 31 Aug 2026 19:22:18 -0700 (PDT) Received: from sw04.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e0d3fdf6sm33287164c88.6.2026.08.31.19.22.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 19:22:18 -0700 (PDT) From: Zong Li To: opensbi@lists.infradead.org, anup@brainfault.org Cc: Zong Li Subject: [PATCH 3/3] docs: firmware: document the OpenSBI firmware header Date: Mon, 31 Aug 2026 19:22:11 -0700 Message-ID: <20260901022211.2619560-4-zong.li@sifive.com> X-Mailer: git-send-email @GIT_VERSION@ In-Reply-To: <20260901022211.2619560-1-zong.li@sifive.com> References: <20260901022211.2619560-1-zong.li@sifive.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260831_192219_918981_3B7308F1 X-CRM114-Status: GOOD ( 25.68 ) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Add docs/firmware/fw_header.md describing the layout of the 128-byte OpenSBI firmware header, the a0/a1/a2 override flags, what a previous booting stage is expected to put in each register, and an exa [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:102e listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 DMARC_PASS DMARC pass policy X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add docs/firmware/fw_header.md describing the layout of the 128-byte OpenSBI firmware header, the a0/a1/a2 override flags, what a previous booting stage is expected to put in each register, and an example of how to patch the header. Also point at it from fw.md, next to the description of the registers the previous booting stage passes. Signed-off-by: Zong Li --- docs/firmware/fw.md | 9 +++ docs/firmware/fw_header.md | 127 +++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 docs/firmware/fw_header.md diff --git a/docs/firmware/fw.md b/docs/firmware/fw.md index d2980967..6b5ff153 100644 --- a/docs/firmware/fw.md +++ b/docs/firmware/fw.md @@ -16,6 +16,11 @@ of RISC-V CPU: * device tree blob address in memory via *a1* register. The address must be aligned to 8 bytes. +A previous booting stage which cannot set up these registers can instead pass +the same information by patching the OpenSBI firmware header, which is present +at the beginning of every OpenSBI firmware image. See *[FW_HEADER]* for +details. + OpenSBI currently supports three different types of firmwares. Firmware with Dynamic Information (*FW_DYNAMIC*) @@ -82,9 +87,13 @@ following documents. * *[FW_PAYLOAD]*: The *Firmware with Payload (FW_PAYLOAD)* is described in more details in the file *fw_payload.md*. +The *OpenSBI firmware header*, which is common to all firmware types, is +described in *[FW_HEADER]*. + [FW_DYNAMIC]: fw_dynamic.md [FW_JUMP]: fw_jump.md [FW_PAYLOAD]: fw_payload.md +[FW_HEADER]: fw_header.md Providing different payloads to OpenSBI Firmware ------------------------------------------------ diff --git a/docs/firmware/fw_header.md b/docs/firmware/fw_header.md new file mode 100644 index 00000000..7dfca111 --- /dev/null +++ b/docs/firmware/fw_header.md @@ -0,0 +1,127 @@ +OpenSBI Firmware Header +======================= + +Every OpenSBI firmware image, regardless of its type (*FW_DYNAMIC*, *FW_JUMP* +or *FW_PAYLOAD*), starts with a fixed 128-byte header. The header serves two +purposes: + +1. it lets the previous booting stage recognize an OpenSBI firmware image and + find out what it was built for, and +2. it gives the previous booting stage a well-known place inside the image to + hand over the boot arguments by patching a few words, instead of setting up + the *a0*, *a1* and *a2* registers. + +The second point matters when the previous booting stage cannot set up those +registers at all. A typical example is a system where the previous booting +stage runs on a dedicated boot processor: it can load and patch the OpenSBI +image in DRAM and then release the application hart that runs OpenSBI, but it +can never execute on that hart and therefore cannot place anything in its +registers. + +The first word of the header is a jump over the header, so the entry point of +the firmware is unchanged: the previous booting stage still jumps to the first +byte of the image. + +Header layout +------------- + +| Offset | Size | Field | +|--------|------|---------------------------------------------------| +| 0x00 | 4 | Jump over the header (a 4-byte `j` instruction) | +| 0x04 | 4 | Magic value, 'OSBI' (0x4942534f) | +| 0x08 | 4 | Header version, currently 1 | +| 0x0c | 4 | XLEN the firmware was built for, 32 or 64 | +| 0x10 | 4 | Firmware size in bytes | +| 0x14 | 4 | Flags, see below | +| 0x18 | 8 | Override value for *a0* | +| 0x20 | 8 | Reserved (upper half of the *a0* value on RV128) | +| 0x28 | 8 | Override value for *a1* | +| 0x30 | 8 | Reserved (upper half of the *a1* value on RV128) | +| 0x38 | 8 | Override value for *a2* | +| 0x40 | 8 | Reserved (upper half of the *a2* value on RV128) | +| 0x48 | 56 | Reserved | + +All fields are little-endian. The layout is deliberately the same for RV32 and +RV64, so the previous booting stage can parse the header, and in particular +check the *XLEN* field, without knowing the XLEN of the firmware upfront. The +override values are 8 bytes wide on both; on RV32 only the lower 4 bytes are +used and the upper 4 bytes must be zero. Each override value is followed by a +reserved 8-byte slot so that the same layout can be extended to RV128 later. + +The *firmware size* field is `_fw_end - _fw_start`, i.e. how much memory the +firmware image occupies once loaded, including the *.bss* section. Note that +this is not the size of the flat binary file, which is smaller because +*.bss* is not stored in the file. OpenSBI also needs some scratch space +beyond the firmware image, so this field alone does not describe everything +the previous booting stage has to reserve. + +Overriding a0, a1 and a2 +------------------------ + +The following flags are defined: + +| Flag | Value | Description | +|-----------------------------|-------|---------------------------------| +| FW_HEADER_FLAGS_OVERRIDE_A0 | 1 << 0| Override *a0* from offset 0x18 | +| FW_HEADER_FLAGS_OVERRIDE_A1 | 1 << 1| Override *a1* from offset 0x28 | +| FW_HEADER_FLAGS_OVERRIDE_A2 | 1 << 2| Override *a2* from offset 0x38 | + +For every flag that is set, OpenSBI replaces the corresponding register with +the value from the header before it looks at the boot arguments. Registers +whose flag is clear are used exactly as passed by the previous booting stage. + +The flags word is zero in a freshly built image, so a previous booting stage +that already passes *a0*, *a1* and *a2* in registers is unaffected and needs +to know nothing about the header. + +The meaning of the registers is unchanged, so the previous booting stage +should patch: + +* *a0* with the hart id of the hart that will enter OpenSBI, +* *a1* with the device tree blob address, which must be 8-byte aligned, and +* *a2* with the address of a *struct fw_dynamic_info*, for a *FW_DYNAMIC* + firmware. The structure itself is not part of the OpenSBI image; the + previous booting stage has to place it in memory that OpenSBI does not + overwrite, which notably excludes the OpenSBI *.bss* section and the + scratch space above the firmware. + +Patching the header +------------------- + +The header is at the very beginning of the image, so all offsets above are +relative to the address the image was loaded at. For example, on RV64: + +```c +#define FW_HEADER_MAGIC_VALUE 0x4942534f +#define FW_HEADER_FLAGS_OVERRIDE_A0 (1 << 0) +#define FW_HEADER_FLAGS_OVERRIDE_A1 (1 << 1) +#define FW_HEADER_FLAGS_OVERRIDE_A2 (1 << 2) + +struct fw_header { + uint32_t jump; + uint32_t magic; + uint32_t version; + uint32_t xlen; + uint32_t size; + uint32_t flags; + uint64_t override_a0; + uint64_t reserved0; + uint64_t override_a1; + uint64_t reserved1; + uint64_t override_a2; + uint64_t reserved2; + uint64_t reserved[7]; +}; + +struct fw_header *hdr = (struct fw_header *)opensbi_load_addr; + +if (hdr->magic != FW_HEADER_MAGIC_VALUE || hdr->xlen != 64) + return -EINVAL; + +hdr->override_a0 = hartid; +hdr->override_a1 = dtb_addr; +hdr->override_a2 = (uint64_t)dynamic_info; +hdr->flags = FW_HEADER_FLAGS_OVERRIDE_A0 | + FW_HEADER_FLAGS_OVERRIDE_A1 | + FW_HEADER_FLAGS_OVERRIDE_A2; +```