diff mbox series

[1/1] arm: rust: Enable Rust support for ARMv7

Message ID 4e0f5932-c7bc-4878-862c-1186cbecd71d@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/1] arm: rust: Enable Rust support for ARMv7 | expand

Commit Message

Christian Schrefl June 7, 2024, 10:30 p.m. UTC
This commit allows building ARMv7 kernels with Rust support.

The rust core library expects some __eabi_... functions
that are not implemented in the kernel.
Those functions are some float operations and __aeabi_uldivmod.

This is based on the code by Sven Van Asbroeck from the original
rust branch and inspired by the AArch version by Jamie Cunliffe.

I have tested the rust samples and a custom simple MMIO module
on on hardware (De1SoC FPGA + Arm A9 CPU).

Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
---
 Documentation/rust/arch-support.rst |  1 +
 arch/arm/Kconfig                    |  1 +
 arch/arm/Makefile                   |  1 +
 rust/Makefile                       | 10 +++++++++-
 rust/bindgen_parameters             |  4 ++++
 rust/compiler_builtins.rs           | 24 ++++++++++++++++++++++++
 scripts/generate_rust_target.rs     |  4 +++-
 7 files changed, 43 insertions(+), 2 deletions(-)

Comments

Miguel Ojeda June 8, 2024, 12:16 p.m. UTC | #1
On Sat, Jun 8, 2024 at 12:30 AM Christian Schrefl
<chrisi.schrefl@gmail.com> wrote:
>
> This is based on the code by Sven Van Asbroeck from the original
> rust branch and inspired by the AArch version by Jamie Cunliffe.

Thanks for mentioning that!

(AArch64 perhaps?)

> I have tested the rust samples and a custom simple MMIO module
> on on hardware (De1SoC FPGA + Arm A9 CPU).

Very nice to have tested it in real hardware, thanks!

(Duplicate "on on").

> +``arm``        Maintained        ARMv7 Little Endian only.

How hard would it be to test and maintain other versions, eventually?
I met Jamie recently, he may have some ideas here.

> -BINDGEN_TARGET_arm64   := aarch64-linux-gnu
> +BINDGEN_TARGET_arm64:= aarch64-linux-gnu

Spurious change?

> +# Depending on how the architecute defines ARCH_SLAB_MINALIGN, bindgen might generate a binding.
> +# Disable this here as there is a const that will always be generated in bindings_helper.c

Typo in "architecute". Also, I guess you mean `.h` instead. Please use
Markdown formatting for consistency with the rest of the file.

> +        panic!("arm uses the builtin rustc target");

Since ARM64 puts the name of the target in the message, it would be
nice to do the same (or perhaps it can be removed from the ARM64 one
otherwise).

Cheers,
Miguel
Geert Stappers June 8, 2024, 12:42 p.m. UTC | #2
On Sat, Jun 08, 2024 at 12:30:12AM +0200, Christian Schrefl wrote:
> --- a/rust/Makefile
> +++ b/rust/Makefile
> @@ -286,7 +286,8 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
>  
>  # Derived from `scripts/Makefile.clang`.
>  BINDGEN_TARGET_x86	:= x86_64-linux-gnu
> -BINDGEN_TARGET_arm64	:= aarch64-linux-gnu
> +BINDGEN_TARGET_arm64:= aarch64-linux-gnu

That white space change is probably accidently.


> +BINDGEN_TARGET_arm	:= arm-linux-gnueabi
>  BINDGEN_TARGET		:= $(BINDGEN_TARGET_$(SRCARCH))
>  
>  # All warnings are inhibited since GCC builds are very experimental,


Groeten
Geert Stappers
Christian Schrefl June 8, 2024, 1:57 p.m. UTC | #3
On 08.06.24 2:16 PM, Miguel Ojeda wrote:
> On Sat, Jun 8, 2024 at 12:30 AM Christian Schrefl
> <chrisi.schrefl@gmail.com> wrote:
>>
>> This is based on the code by Sven Van Asbroeck from the original
>> rust branch and inspired by the AArch version by Jamie Cunliffe.
> 
> Thanks for mentioning that!
> 
> (AArch64 perhaps?)

Ah yes I meant AArch64. Fixed it locally.

>> I have tested the rust samples and a custom simple MMIO module
>> on on hardware (De1SoC FPGA + Arm A9 CPU).
> 
> Very nice to have tested it in real hardware, thanks!
> 
> (Duplicate "on on").

I fixed that locally, but forgot to run format-patch again, sorry! 

>> +``arm``        Maintained        ARMv7 Little Endian only.
> 
> How hard would it be to test and maintain other versions, eventually?
> I met Jamie recently, he may have some ideas here.

I think it would just be setting the correct rust target,
but I have no hardware to test it and I think its best to
only do v7 for the initial support.

>> -BINDGEN_TARGET_arm64   := aarch64-linux-gnu
>> +BINDGEN_TARGET_arm64:= aarch64-linux-gnu
> 
> Spurious change?

I've changed that so the := aligns with the others, but I can
remove that for v2 if you want

>> +# Depending on how the architecute defines ARCH_SLAB_MINALIGN, bindgen might generate a binding.
>> +# Disable this here as there is a const that will always be generated in bindings_helper.c
> 
> Typo in "architecute". Also, I guess you mean `.h` instead. Please use
> Markdown formatting for consistency with the rest of the file.

Fixed.

>> +        panic!("arm uses the builtin rustc target");
> 
> Since ARM64 puts the name of the target in the message, it would be
> nice to do the same (or perhaps it can be removed from the ARM64 one
> otherwise).

I can add the target here but then the message would have to depend
on the sub architecture if we support v6 in the future. 

> Cheers,
> Miguel
Andrew Lunn June 10, 2024, 7 p.m. UTC | #4
> --- a/Documentation/rust/arch-support.rst
> +++ b/Documentation/rust/arch-support.rst
> @@ -15,6 +15,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
>  =============  ================  ==============================================
>  Architecture   Level of support  Constraints
>  =============  ================  ==============================================
> +``arm``        Maintained        ARMv7 Little Endian only.

Might be a FAQ, but what does Maintained mean here? Should you be
adding yourself to the RUST entry in MAINTAINERS? You are Maintaining
Rust on ARMv7 and so should be given credit/responsibility for that in
MAINTAINERS?

       Andrew
Christian Schrefl June 10, 2024, 7:37 p.m. UTC | #5
On 10.06.24 9:00 PM, Andrew Lunn wrote:
>> --- a/Documentation/rust/arch-support.rst
>> +++ b/Documentation/rust/arch-support.rst
>> @@ -15,6 +15,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
>>  =============  ================  ==============================================
>>  Architecture   Level of support  Constraints
>>  =============  ================  ==============================================
>> +``arm``        Maintained        ARMv7 Little Endian only.
> 
> Might be a FAQ, but what does Maintained mean here? Should you be
> adding yourself to the RUST entry in MAINTAINERS? You are Maintaining
> Rust on ARMv7 and so should be given credit/responsibility for that in
> MAINTAINERS?

From my side I can/will take a look if there are issues/patches related to this, but I 
can't be sure how fast I'll be able to respond and I don't feel qualified to handle
larger or more complicated issues myself.

But there isn't a MAINTAINERS entry depending on the architecture, so I'm not sure
who will be responsible for this.

Miguel how is the support handled for the other architectures?
Miguel Ojeda June 10, 2024, 9:19 p.m. UTC | #6
On Mon, Jun 10, 2024 at 9:37 PM Christian Schrefl
<chrisi.schrefl@gmail.com> wrote:
>
> Miguel how is the support handled for the other architectures?

The arch maintainers are the ones taking the patches through their
trees and so on (with the initial exception of x86).

Of course, if you want to contribute to that, that is great. If an
entry is wanted/needed, then a possibility is a sub-entry to the
architecture.

Cheers,
Miguel
diff mbox series

Patch

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index b13e19d84744..4bf5205f526d 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -15,6 +15,7 @@  support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 =============  ================  ==============================================
 Architecture   Level of support  Constraints
 =============  ================  ==============================================
+``arm``        Maintained        ARMv7 Little Endian only.
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
 ``riscv``      Maintained        ``riscv64`` only.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ee5115252aac..f07149fe078b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -126,6 +126,7 @@  config ARM
 	select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
+	select HAVE_RUST if CPU_LITTLE_ENDIAN && CPU_32v7
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 71afdd98ddf2..9cc10e32e8be 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -150,6 +150,7 @@  endif
 KBUILD_CPPFLAGS	+=$(cpp-y)
 KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include asm/unified.h -msoft-float
+KBUILD_RUSTFLAGS += --target=arm-unknown-linux-gnueabi
 
 CHECKFLAGS	+= -D__arm__
 
diff --git a/rust/Makefile b/rust/Makefile
index f70d5e244fee..ef177ffb68a8 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -286,7 +286,8 @@  bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
 
 # Derived from `scripts/Makefile.clang`.
 BINDGEN_TARGET_x86	:= x86_64-linux-gnu
-BINDGEN_TARGET_arm64	:= aarch64-linux-gnu
+BINDGEN_TARGET_arm64:= aarch64-linux-gnu
+BINDGEN_TARGET_arm	:= arm-linux-gnueabi
 BINDGEN_TARGET		:= $(BINDGEN_TARGET_$(SRCARCH))
 
 # All warnings are inhibited since GCC builds are very experimental,
@@ -413,6 +414,13 @@  redirect-intrinsics = \
 	__muloti4 __multi3 \
 	__udivmodti4 __udivti3 __umodti3
 
+ifdef CONFIG_ARM
+	# Add eabi initrinsics for ARM 32-bit
+	redirect-intrinsics += \
+		__aeabi_fadd __aeabi_fmul __aeabi_fcmpeq __aeabi_fcmple __aeabi_fcmplt __aeabi_fcmpun \
+		__aeabi_dadd __aeabi_dmul __aeabi_dcmple __aeabi_dcmplt __aeabi_dcmpun \
+		__aeabi_uldivmod
+endif
 ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),)
 	# These intrinsics are defined for ARM64 and RISCV64
 	redirect-intrinsics += \
diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters
index a721d466bee4..bf0148b3019e 100644
--- a/rust/bindgen_parameters
+++ b/rust/bindgen_parameters
@@ -24,3 +24,7 @@ 
 # These functions use the `__preserve_most` calling convention, which neither bindgen
 # nor Rust currently understand, and which Clang currently declares to be unstable.
 --blocklist-function __list_.*_report
+
+# Depending on how the architecute defines ARCH_SLAB_MINALIGN, bindgen might generate a binding.
+# Disable this here as there is a const that will always be generated in bindings_helper.c
+--blocklist-item ARCH_SLAB_MINALIGN
diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
index bba2922c6ef7..c37142b16a45 100644
--- a/rust/compiler_builtins.rs
+++ b/rust/compiler_builtins.rs
@@ -70,5 +70,29 @@  pub extern "C" fn $ident() {
     __umodti3,
 });
 
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`f32` should not be used", {
+    __aeabi_fadd,
+    __aeabi_fmul,
+    __aeabi_fcmpeq,
+    __aeabi_fcmple,
+    __aeabi_fcmplt,
+    __aeabi_fcmpun,
+});
+
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`f64` should not be used", {
+    __aeabi_dadd,
+    __aeabi_dmul,
+    __aeabi_dcmple,
+    __aeabi_dcmplt,
+    __aeabi_dcmpun,
+});
+
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`u64` division/modulo should not be used", {
+    __aeabi_uldivmod,
+});
+
 // NOTE: if you are adding a new intrinsic here, you should also add it to
 // `redirect-intrinsics` in `rust/Makefile`.
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 641b713a033a..acfcf2e22e28 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -148,7 +148,9 @@  fn main() {
     let mut ts = TargetSpec::new();
 
     // `llvm-target`s are taken from `scripts/Makefile.clang`.
-    if cfg.has("ARM64") {
+    if cfg.has("ARM") {
+        panic!("arm uses the builtin rustc target");
+    } else if cfg.has("ARM64") {
         panic!("arm64 uses the builtin rustc aarch64-unknown-none target");
     } else if cfg.has("RISCV") {
         if cfg.has("64BIT") {