From patchwork Tue Mar 2 15:25:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Chen X-Patchwork-Id: 1446774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=A09otftH; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256 header.s=casper.20170209 header.b=CSBQCkg/; 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=FuohccnH; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DrMh51zpnz9s1l for ; Thu, 4 Mar 2021 05:18:45 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id: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=E+jzgsSdOWUqdgeSrIEN5WPkgmV5ACUg4tkEx2Tc7Os=; b=A09otftH2R1ERAM5vV0yBWa9CT OUR3N+9nRCDT4/0qW/XkOPbGWEy8TCrzquL/ylRrJdl17Wln4WsnruYale/vk7fYEwkkTarvAVbpw QlWHXvPR1NZofkRjVN6+jlWeshrmSCgNrw/+VfeGmHfTP4wUQYvPCYyhPBzCLZUCFM3ZCb7Lv2CpT 0Iks+Qo3+qDsvT6CGcJBOUGfXGM10XlX+CLl94ksWXfKRxt7mArGzXbXQMKq7r9JPjPOSUDkZFCXY MvF/MzDBo4ev8ADQVS3KKHpz4FL+yTnuyhGByRjNP2UZI/d03SStao1Am5Ydm8vsG/ZEZyhw9G+r2 gvttAJXg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lHW4x-005zB5-Qd; Wed, 03 Mar 2021 18:18:35 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lHSzs-005Gpj-8N for opensbi@desiato.infradead.org; Wed, 03 Mar 2021 15:01:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=2OntgLclqmeeUJ4y4ZACRqTnck5RYuCemmByyq6RD1s=; b=CSBQCkg/vuar3FKXdu2WIwvyCs IqFRP8Or2ewUQQvpUPJvaueYjMYTGf3e9EWKiv0pcCvoQdSrkGjHxE+tTeF4a3hUsqPmYSP+yg++x ez12K5iQDI5U2q15fUXigFQf881rH6kI+c/giND6DmQmj7bOAIxF2cPikHvMSVItdXiCqVmYOnHCp 1qukG4JLCPbUcmvKm+22pCrBd9q+mxIvgZ3SpKJyZIaR+11PB3/N+L8yS+rIMavigX/3ui3OmXRRN a+I6eJvRcETvK7mibpE4Ynoe3RA04qmGPwtjz2okUBXhWBXPr+gYgZ10wsADtfyqbKWU31vW9D8pL xhKBl/Ww==; Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]) by casper.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lH6vO-00HLcb-Ug for opensbi@lists.infradead.org; Tue, 02 Mar 2021 15:27:13 +0000 Received: by mail-pg1-x530.google.com with SMTP id e6so14021958pgk.5 for ; Tue, 02 Mar 2021 07:27:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2OntgLclqmeeUJ4y4ZACRqTnck5RYuCemmByyq6RD1s=; b=FuohccnHupOO3shnkSQj98+u3fdQDzRvdwVpHCbiFDu9+fIU1o4YCUWRB4FCFv0rdg AlO/XoeYYleOOSRdjLD5pGVFh2GJgfr6vcglJtKYwwHn5bgmhkbTXN+lU5i+ZjSqp1RH iNvwoNGloxnx5HsTrBozS8q/v1m/KS5VKj7wuI4OVqj2RALt9w8P1X+xxO9hBQL+bsKk 4EnrWXBD08LVVv9n/OdQWmbKYUpfaQ8Zkwpqq8E8oEhtnyA3qKYZpVHWjgSoLECmWkKd iY4VcnR9Q7cAGOxdDi6P7FU8ZymZKklViz/Dbwc8v0qPa6LMAEMRG/9+5HOTc6nKhQnI VaVg== 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=2OntgLclqmeeUJ4y4ZACRqTnck5RYuCemmByyq6RD1s=; b=BqYySHhWENC0KPz608JAMjbP9ObHTxvxKXCMUCpzSJEZma4pRi+VBHFi6aa7pVmNyy 14X+QFC9+RpwPuFTz8woPqgs6+clElKhOiJqZfRVCzadJdApks9RkEM6Tgut6ei1Lnmf PKHTV5MfxuFwYMTqzXsu9QuXGpIwrY+N8LqKVWNqF0xGmBMaFPKHmqN/RL+zBP4omSAN 6L22c0/NVHE/mNmimW3gvLiRX9RjU+1TMc2x1YGVntMLG8jC759FxmMbclbFWT/omWip JoRP4saLHupM5AGWoVYLQ8HfblugEtNybFKSw3WmXurYV+h03iKB2ncFS1nBYM3kHb5U nVkQ== X-Gm-Message-State: AOAM530woq75ZM107fDA+qGMl/Kglweut6WUvAcb6XSzRhP+nWs1TNN1 aruWHmyzHHnYqSRRrMTy+sKrKC8Exve2Tg== X-Google-Smtp-Source: ABdhPJw5Y/Av2jZCDJetoUknwumJ5J9cYLwXgiTAdLcOi7x55oZYkbWkYWEdCzZ39fhJ0z1xGGn52A== X-Received: by 2002:a62:1cd4:0:b029:1ee:9db0:3dc3 with SMTP id c203-20020a621cd40000b02901ee9db03dc3mr3794054pfc.59.1614698759161; Tue, 02 Mar 2021 07:25:59 -0800 (PST) Received: from localhost.localdomain (61-230-7-198.dynamic-ip.hinet.net. [61.230.7.198]) by smtp.gmail.com with ESMTPSA id r123sm21630052pfc.211.2021.03.02.07.25.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Mar 2021 07:25:58 -0800 (PST) From: Vincent Chen To: opensbi@lists.infradead.org Cc: vincent.chen@sifive.com Subject: [PATCH 1/3] firmware: Support position independent execution Date: Tue, 2 Mar 2021 23:25:50 +0800 Message-Id: <1614698752-16085-2-git-send-email-vincent.chen@sifive.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1614698752-16085-1-git-send-email-vincent.chen@sifive.com> References: <1614698752-16085-1-git-send-email-vincent.chen@sifive.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210302_152713_435952_4E7E1EC0 X-CRM114-Status: GOOD ( 17.34 ) X-Spam-Note: SpamAssassin invocation failed 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: , MIME-Version: 1.0 Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Enable OpenSBI to support position independent execution. Because the position independent code will cause an additional GOT reference when accessing the global variables, it will reduce performance a bit. Therefore, the position independent execution is disabled by default. Users can through specifying "FW_PIC=y" on the make command to enable this feature. In theory, after enabling position-independent execution, the OpenSBI can run at arbitrary address with appropriate alignment. Therefore, the original relocation mechanism will be skipped. In other words, OpenSBI will directly run at the load address without any code movement. Signed-off-by: Vincent Chen --- Makefile | 10 +++++++ firmware/fw_base.S | 70 +++++++++++++++++++++++++++++++++++++++++++++---- firmware/fw_base.ldS | 13 +++++++++ firmware/fw_jump.S | 10 +++++++ firmware/fw_payload.S | 6 +++++ include/sbi/riscv_elf.h | 9 +++++++ 6 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 include/sbi/riscv_elf.h diff --git a/Makefile b/Makefile index d6f097d..0bebdf3 100644 --- a/Makefile +++ b/Makefile @@ -202,6 +202,9 @@ endif GENFLAGS += $(libsbiutils-genflags-y) GENFLAGS += $(platform-genflags-y) GENFLAGS += $(firmware-genflags-y) +ifeq ($(FW_PIC),y) +GENFLAGS += -DFW_PIC +endif CFLAGS = -g -Wall -Werror -ffreestanding -nostdlib -fno-strict-aliasing -O2 CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls @@ -211,7 +214,11 @@ CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL) CFLAGS += $(GENFLAGS) CFLAGS += $(platform-cflags-y) CFLAGS += $(firmware-cflags-y) +ifeq ($(FW_PIC),y) +CFLAGS += -fPIE -pie +else CFLAGS += -fno-pie -no-pie +endif CPPFLAGS += $(GENFLAGS) CPPFLAGS += $(platform-cppflags-y) @@ -231,6 +238,9 @@ ARFLAGS = rcs ELFFLAGS += -Wl,--build-id=none -N -static-libgcc -lgcc ELFFLAGS += $(platform-ldflags-y) ELFFLAGS += $(firmware-ldflags-y) +ifeq ($(FW_PIC),y) +ELFFLAGS += -Wl,--no-dynamic-linker +endif MERGEFLAGS += -r MERGEFLAGS += -b elf$(PLATFORM_RISCV_XLEN)-littleriscv diff --git a/firmware/fw_base.S b/firmware/fw_base.S index ab33e11..8f8e5dc 100644 --- a/firmware/fw_base.S +++ b/firmware/fw_base.S @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,9 @@ 999: .endm +#ifdef FW_PIC + .option pic +#endif .section .entry, "ax", %progbits .align 3 .globl _start @@ -48,7 +52,7 @@ _start: /* Find preferred boot HART id */ MOV_3R s0, a0, s1, a1, s2, a2 - call fw_boot_hart + lla t0, _start_hang add a6, a0, zero MOV_3R a0, s0, a1, s1, a2, s2 li a7, -1 @@ -57,16 +61,67 @@ _start: bne a0, a6, _wait_relocate_copy_done _try_lottery: /* Jump to relocation wait loop if we don't get relocation lottery */ - la a6, _relocate_lottery + lla a6, _relocate_lottery li a7, 1 amoadd.w a6, a7, (a6) bnez a6, _wait_relocate_copy_done /* Save load address */ - la t0, _load_start - la t1, _start + lla t0, _load_start + lla t1, _start REG_S t1, 0(t0) +#ifdef FW_PIC + /* relocate the global table content */ + lla t0, _link_start + REG_L t0, 0(t0) + sub t2, t1, t0 + lla t3, _runtime_offset + REG_S t2, (t3) + lla t0, __rel_dyn_start + lla t1, __rel_dyn_end + beq t0, t1, _relocate_done + j 5f +2: + REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */ + li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ + bne t5, t3, 3f + REG_L t3, -(REGBYTES*3)(t0) + REG_L t5, -(REGBYTES)(t0) /* t5 <-- addend */ + add t5, t5, t2 + add t3, t3, t2 + REG_S t5, 0(t3) /* store runtime address to the GOT entry */ + j 5f + +3: + lla t4, __dyn_sym_start + +4: + REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */ + srli t6, t5, SYM_INDEX /* t6 <--- sym table index */ + andi t5, t5, 0xFF /* t5 <--- relocation type */ + li t3, RELOC_TYPE + bne t5, t3, 5f + + /* address R_RISCV_64 or R_RISCV_32 cases*/ + REG_L t3, -(REGBYTES*3)(t0) + li t5, SYM_SIZE + mul t6, t6, t5 + add s5, t4, t6 + REG_L t6, -(REGBYTES)(t0) /* t0 <-- addend */ + REG_L t5, REGBYTES(s5) + add t5, t5, t6 + add t5, t5, t2 /* t5 <-- location to fix up in RAM */ + add t3, t3, t2 /* t3 <-- location to fix up in RAM */ + REG_S t5, 0(t3) /* store runtime address to the variable */ + +5: + addi t0, t0, (REGBYTES*3) + ble t0, t1, 2b + j _relocate_done +_wait_relocate_copy_done: + j _wait_for_boot_hart +#else /* Relocate if load address != link address */ _relocate: la t0, _link_start @@ -137,6 +192,7 @@ _wait_relocate_copy_done: nop bgt t4, t5, 1b jr t3 +#endif _relocate_done: /* @@ -144,12 +200,14 @@ _relocate_done: * Use _boot_status copy relative to the load address */ la t0, _boot_status +#ifndef FW_PIC la t1, _link_start REG_L t1, 0(t1) la t2, _load_start REG_L t2, 0(t2) sub t0, t0, t1 add t0, t0, t2 +#endif li t1, BOOT_STATUS_RELOCATE_DONE REG_S t1, 0(t0) fence rw, rw @@ -446,6 +504,8 @@ _skip_trap_exit_rv32_hyp: j _start_hang .align 3 +_runtime_offset: + RISCV_PTR 0 _relocate_lottery: RISCV_PTR 0 _boot_status: @@ -453,7 +513,7 @@ _boot_status: _load_start: RISCV_PTR _fw_start _link_start: - RISCV_PTR _fw_start + RISCV_PTR FW_TEXT_START _link_end: RISCV_PTR _fw_reloc_end diff --git a/firmware/fw_base.ldS b/firmware/fw_base.ldS index 0ac75f2..3904959 100644 --- a/firmware/fw_base.ldS +++ b/firmware/fw_base.ldS @@ -61,6 +61,19 @@ PROVIDE(_data_end = .); } + .dynsym : { + PROVIDE(__dyn_sym_start = .); + *(.dynsym) + PROVIDE(__dyn_sym_end = .); + } + + .rela.dyn : { + PROVIDE(__rel_dyn_start = .); + *(.rela*) + . = ALIGN(8); + PROVIDE(__rel_dyn_end = .); + } + . = ALIGN(0x1000); /* Ensure next section is page aligned */ .bss : diff --git a/firmware/fw_jump.S b/firmware/fw_jump.S index 8553f8c..3cce3f7 100644 --- a/firmware/fw_jump.S +++ b/firmware/fw_jump.S @@ -46,6 +46,11 @@ fw_save_info: fw_next_arg1: #ifdef FW_JUMP_FDT_ADDR li a0, FW_JUMP_FDT_ADDR +#ifdef FW_PIC + la a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif #else add a0, a1, zero #endif @@ -61,6 +66,11 @@ fw_next_arg1: fw_next_addr: la a0, _jump_addr REG_L a0, (a0) +#ifdef FW_PIC + la a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif ret .section .entry, "ax", %progbits diff --git a/firmware/fw_payload.S b/firmware/fw_payload.S index 1ef121e..18b51d0 100644 --- a/firmware/fw_payload.S +++ b/firmware/fw_payload.S @@ -46,6 +46,12 @@ fw_save_info: fw_next_arg1: #ifdef FW_PAYLOAD_FDT_ADDR li a0, FW_PAYLOAD_FDT_ADDR +#ifdef FW_PIC + la a1, _runtime_offset + REG_L a1, (a1) + add a0, a0, a1 +#endif + #else add a0, a1, zero #endif diff --git a/include/sbi/riscv_elf.h b/include/sbi/riscv_elf.h new file mode 100644 index 0000000..cf211ac --- /dev/null +++ b/include/sbi/riscv_elf.h @@ -0,0 +1,9 @@ +#include + +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 + +#define RELOC_TYPE __REG_SEL(R_RISCV_64, R_RISCV_32) +#define SYM_INDEX __REG_SEL(0x20, 0x8) +#define SYM_SIZE __REG_SEL(0x18,0x10)