diff mbox series

[3/3] rust: Enable for MIPS

Message ID 20240903-mips-rust-v1-3-0fdf0b2fd58f@flygoat.com
State Not Applicable
Headers show
Series rust: Initial MIPS support | expand

Commit Message

Jiaxun Yang Sept. 3, 2024, 5:14 p.m. UTC
Enable rust for linux by implement generate_rust_target.rs
and select relevant Kconfig options.

We don't use builtin target as there is no sutiable baremetal
target for us that can cover all ISA variants supported by kernel.

Link: https://github.com/Rust-for-Linux/linux/issues/107
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 Documentation/rust/arch-support.rst                |  1 +
 .../translations/zh_CN/rust/arch-support.rst       |  1 +
 arch/mips/Kconfig                                  |  2 +
 scripts/generate_rust_target.rs                    | 64 ++++++++++++++++++++++
 4 files changed, 68 insertions(+)

Comments

Miguel Ojeda Sept. 3, 2024, 5:44 p.m. UTC | #1
On Tue, Sep 3, 2024 at 7:15 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
> We don't use builtin target as there is no sutiable baremetal
> target for us that can cover all ISA variants supported by kernel.

Since we should try to go away from using `target.json`: what was not
possible to enable via e.g. `-Ctarget-features` or other flags? i.e. I
see the `+mips*` features there in the supported list, and from a
quick test the data layout also seems to match, but I assume I missed
something.

If it is not possible, then we should definitely ping upstream Rust about it. :)

Cheers,
Miguel
Jiaxun Yang Sept. 3, 2024, 5:53 p.m. UTC | #2
在2024年9月3日九月 下午6:44,Miguel Ojeda写道:
> On Tue, Sep 3, 2024 at 7:15 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>>
>> We don't use builtin target as there is no sutiable baremetal
>> target for us that can cover all ISA variants supported by kernel.
>
> Since we should try to go away from using `target.json`: what was not
> possible to enable via e.g. `-Ctarget-features` or other flags? i.e. I
> see the `+mips*` features there in the supported list, and from a
> quick test the data layout also seems to match, but I assume I missed
> something.
>
> If it is not possible, then we should definitely ping upstream Rust about it. :)
Hi Miguel,

Thanks for your review!

Triples defined for MIPS bare-metal target is surprisingly lacking, we do have
little-endian 32-bit bare-metal target mipsel-unknown-none but big-endian and
64 bit variants are missing.

Also, those triples all assumed +mips32r2 as baseline ISA, but kernel actually needs
some other ISA variant features.

Thanks
>
> Cheers,
> Miguel
Miguel Ojeda Sept. 3, 2024, 6:17 p.m. UTC | #3
On Tue, Sep 3, 2024 at 7:53 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
> Thanks for your review!

You're welcome!

> Triples defined for MIPS bare-metal target is surprisingly lacking, we do have
> little-endian 32-bit bare-metal target mipsel-unknown-none but big-endian and
> 64 bit variants are missing.

Hmm... Sorry if this may be too naive, since I have no expertise on
MIPS, but I see some triples that match the LLVM ones you specify in
the patch:

    rustc --print target-list | grep mips

> Also, those triples all assumed +mips32r2 as baseline ISA, but kernel actually needs
> some other ISA variant features.

I guess you mean you are getting the warning about the
unknown/unstable feature passed to the backend? i.e. `rustc` knows
about those LLVM ones and forwards them when enabled via
`-Ctarget-feature` (with a warning):

    rustc --target mips64-unknown-linux-gnuabi64 --print target-features

So they would need to be added to the list at [1] (or targeted flags created).

Until those do not emit a warning, it is fine using the `target.json`,
but I wanted to understand if there is something else you may need,
since we will need to eventually avoid the `target.json`, so it is
best asking upstream as soon as possible.

Thanks!

[1] https://github.com/rust-lang/rust/blob/d6c8169c186ab16a3404cd0d0866674018e8a19e/compiler/rustc_target/src/target_features.rs#L368

Cheers,
Miguel
Jiaxun Yang Sept. 3, 2024, 6:31 p.m. UTC | #4
在2024年9月3日九月 下午7:17,Miguel Ojeda写道:
[...]
>
> I guess you mean you are getting the warning about the
> unknown/unstable feature passed to the backend? i.e. `rustc` knows
> about those LLVM ones and forwards them when enabled via
> `-Ctarget-feature` (with a warning):
>
>     rustc --target mips64-unknown-linux-gnuabi64 --print target-features
>
> So they would need to be added to the list at [1] (or targeted flags created).
>
> Until those do not emit a warning, it is fine using the `target.json`,
> but I wanted to understand if there is something else you may need,
> since we will need to eventually avoid the `target.json`, so it is
> best asking upstream as soon as possible.

Ahh thanks for the elaboration.

So there are some targets vs feature stuff which is still not clear for
rust upstream.

For example, on ISA level (things like +mips64r2, +mips3), currently for
rust upstream, it is handled by target name. (i.e. regular mips64-unknown-linux-gnuabi64
triple would pass +mips64r2 to backend, mips64isar6-unknown-linux-gnuabi64
would pass +mips64r6).

However, kernel supports many ISA variants that are not defined by any rust target
triple, I'm not really sure if it's appropriate to define them all in upstream.

The same applies to +soft-float and +noabicalls options as well. It seems like
+soft-float and +noabicalls are only enabled by bare-metal toolchains as rust
recognise them as a target defined features.

Thanks
>
> Thanks!
>
> [1] 
> https://github.com/rust-lang/rust/blob/d6c8169c186ab16a3404cd0d0866674018e8a19e/compiler/rustc_target/src/target_features.rs#L368
>
> Cheers,
> Miguel
Miguel Ojeda Sept. 3, 2024, 7:01 p.m. UTC | #5
On Tue, Sep 3, 2024 at 8:32 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
> Ahh thanks for the elaboration.

You're welcome!

> However, kernel supports many ISA variants that are not defined by any rust target
> triple, I'm not really sure if it's appropriate to define them all in upstream.

They need to be in upstream Rust somehow, because upstream Rust does
not want to stabilize `target.json` since it is too tied to LLVM (as
far as we have been told). Whether that is via `-Ctarget-feature`, or a
new `-Cglobal-target-feature`, or specific flags like `-Zfixed-x18`
(originally `-Ctarget-feature=+reserve-x18`), or (many) new target
triples for different combinations, or something else, it depends on
the case and what upstream Rust wants to do.

That is why we should tell them what is needed, ideally in a new issue
in upstream Rust, and link it in
https://github.com/Rust-for-Linux/linux/issues/355 (please see that
list for similar examples).

I hope that explains a bit more the context.

Cheers,
Miguel
Jiaxun Yang Sept. 4, 2024, 7:38 a.m. UTC | #6
在2024年9月3日九月 下午8:01,Miguel Ojeda写道:
> On Tue, Sep 3, 2024 at 8:32 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>>
>> Ahh thanks for the elaboration.
>
> You're welcome!
>
>> However, kernel supports many ISA variants that are not defined by any rust target
>> triple, I'm not really sure if it's appropriate to define them all in upstream.
>
> They need to be in upstream Rust somehow, because upstream Rust does
> not want to stabilize `target.json` since it is too tied to LLVM (as
> far as we have been told). Whether that is via `-Ctarget-feature`, or a
> new `-Cglobal-target-feature`, or specific flags like `-Zfixed-x18`
> (originally `-Ctarget-feature=+reserve-x18`), or (many) new target
> triples for different combinations, or something else, it depends on
> the case and what upstream Rust wants to do.
>
> That is why we should tell them what is needed, ideally in a new issue
> in upstream Rust, and link it in
> https://github.com/Rust-for-Linux/linux/issues/355 (please see that
> list for similar examples).

Seems like this topic is covered by an existing issue

Reported at:
https://github.com/rust-embedded/wg/issues/792#issuecomment-2328133517

Thanks!
>
> I hope that explains a bit more the context.
>
> Cheers,
> Miguel
Miguel Ojeda Sept. 4, 2024, 8:28 a.m. UTC | #7
On Wed, Sep 4, 2024 at 9:38 AM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
> Reported at:
> https://github.com/rust-embedded/wg/issues/792#issuecomment-2328133517

Thanks for the link! Added to our bullet point about the target spec
file in https://github.com/Rust-for-Linux/linux/issues/2.

Cheers,
Miguel
diff mbox series

Patch

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 750ff371570a..ab6c0ae5a407 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -17,6 +17,7 @@  Architecture   Level of support  Constraints
 =============  ================  ==============================================
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
+``mips``       Maintained        \-
 ``riscv``      Maintained        ``riscv64`` only.
 ``um``         Maintained        \-
 ``x86``        Maintained        ``x86_64`` only.
diff --git a/Documentation/translations/zh_CN/rust/arch-support.rst b/Documentation/translations/zh_CN/rust/arch-support.rst
index abd708d48f82..1eaa6c3297ac 100644
--- a/Documentation/translations/zh_CN/rust/arch-support.rst
+++ b/Documentation/translations/zh_CN/rust/arch-support.rst
@@ -21,6 +21,7 @@ 
 =============  ================  ==============================================
 ``arm64``      Maintained        只有小端序
 ``loongarch``  Maintained        \-
+``mips``       Maintained        \-
 ``riscv``      Maintained        只有 ``riscv64``
 ``um``         Maintained        只有 ``x86_64``
 ``x86``        Maintained        只有 ``x86_64``
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 43da6d596e2b..a91f0a4fd8e9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -90,6 +90,8 @@  config MIPS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
+	select HAVE_RUST
+	select HAVE_GENERATE_RUST_TARGET
 	select HAVE_SPARSE_SYSCALL_NR
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 863720777313..2b8054f17c47 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -141,6 +141,13 @@  fn has(&self, option: &str) -> bool {
         let option = "CONFIG_".to_owned() + option;
         self.0.contains_key(&option)
     }
+
+    /// Returns the value of the option in the configuration.
+    /// The argument must be passed without the `CONFIG_` prefix.
+    fn get(&self, option: &str) -> Option<&String> {
+        let option = "CONFIG_".to_owned() + option;
+        self.0.get(&option)
+    }
 }
 
 fn main() {
@@ -203,6 +210,63 @@  fn main() {
         ts.push("target-pointer-width", "32");
     } else if cfg.has("LOONGARCH") {
         panic!("loongarch uses the builtin rustc loongarch64-unknown-none-softfloat target");
+    } else if cfg.has("MIPS") {
+        let mut features = "+soft-float,+noabicalls".to_string();
+
+        if cfg.has("64BIT") {
+            ts.push("arch", "mips64");
+            ts.push("abi", "abi64");
+            cfg.get("TARGET_ISA_REV").map(|isa_rev| {
+                let feature = match isa_rev.as_str() {
+                    "1" => ",+mips64",
+                    "2" => ",+mips64r2",
+                    "5" => ",+mips64r5",
+                    "6" => ",+mips64r6",
+                    _ => ",+mips3",
+                };
+                features += feature;
+            });
+
+            ts.push("features", features);
+            if cfg.has("CPU_BIG_ENDIAN") {
+                ts.push(
+                    "data-layout",
+                    "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128",
+                );
+                ts.push("llvm-target", "mips64-unknown-linux-gnuabi64");
+            } else {
+                ts.push(
+                    "data-layout",
+                    "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128",
+                );
+                ts.push("llvm-target", "mips64el-unknown-linux-gnuabi64");
+            }
+            ts.push("target-pointer-width", "64");
+        } else {
+            ts.push("arch", "mips");
+            cfg.get("TARGET_ISA_REV").map(|isa_rev| {
+                let feature = match isa_rev.as_str() {
+                    "1" => ",+mips32",
+                    "2" => ",+mips32r2",
+                    "5" => ",+mips32r5",
+                    "6" => ",+mips32r6",
+                    _ => ",+mips2",
+                };
+                features += feature;
+            });
+
+            ts.push("features", features);
+            if cfg.has("CPU_BIG_ENDIAN") {
+                ts.push("data-layout",
+                        "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64");
+                ts.push("llvm-target", "mips-unknown-linux-gnu");
+            } else {
+                ts.push("data-layout",
+                        "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64");
+                ts.push("llvm-target", "mipsel-unknown-linux-gnu");
+            }
+            ts.push("target-pointer-width", "32");
+        }
     } else {
         panic!("Unsupported architecture");
     }