]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: Adjust misc routines for 32BIT/64BIT
authorHuacai Chen <chenhuacai@loongson.cn>
Mon, 8 Dec 2025 10:09:17 +0000 (18:09 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Mon, 8 Dec 2025 10:09:17 +0000 (18:09 +0800)
Adjust misc routines for both 32BIT and 64BIT, including: bitops, bswap,
checksum, string, jump label, unaligned access emulator, suspend/wakeup
routines, etc.

Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/bitops.h
arch/loongarch/include/asm/checksum.h
arch/loongarch/include/asm/jump_label.h
arch/loongarch/include/asm/string.h
arch/loongarch/kernel/unaligned.c
arch/loongarch/lib/bswapdi.c [new file with mode: 0644]
arch/loongarch/lib/bswapsi.c [new file with mode: 0644]
arch/loongarch/lib/unaligned.S
arch/loongarch/power/platform.c
arch/loongarch/power/suspend_asm.S

index 69e00f8d8034166af1062ef250fc97a87ecd87aa..411106bf99026ec5b0d9bd1ecc2a12007d59fc83 100644 (file)
 
 #include <asm/barrier.h>
 
+#ifdef CONFIG_32BIT_REDUCED
+
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/__fls.h>
+
+#else /* CONFIG_32BIT_STANDARD || CONFIG_64BIT  */
+
 #include <asm-generic/bitops/builtin-ffs.h>
 #include <asm-generic/bitops/builtin-fls.h>
 #include <asm-generic/bitops/builtin-__ffs.h>
 #include <asm-generic/bitops/builtin-__fls.h>
 
+#endif
+
 #include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/fls64.h>
 
index cabbf6af44c43acd6be89ed60322b05e6fce3007..cc2754e0aa251236e449483ed6911a0fe93ad0a7 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/bitops.h>
 #include <linux/in6.h>
 
+#ifdef CONFIG_64BIT
+
 #define _HAVE_ARCH_IPV6_CSUM
 __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
                        const struct in6_addr *daddr,
@@ -61,6 +63,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 extern unsigned int do_csum(const unsigned char *buff, int len);
 #define do_csum do_csum
 
+#endif
+
 #include <asm-generic/checksum.h>
 
 #endif /* __ASM_CHECKSUM_H */
index 4000c7603d8e36feabe9acce5d834d450e76aa69..dcaecf69ea5a6064177a7b829cc1e4ec19a6f569 100644 (file)
 #ifndef __ASSEMBLER__
 
 #include <linux/types.h>
+#include <linux/stringify.h>
+#include <asm/asm.h>
 
 #define JUMP_LABEL_NOP_SIZE    4
 
+#ifdef CONFIG_32BIT
+#define JUMP_LABEL_TYPE                ".long "
+#else
+#define JUMP_LABEL_TYPE                ".quad "
+#endif
+
 /* This macro is also expanded on the Rust side. */
 #define JUMP_TABLE_ENTRY(key, label)                   \
         ".pushsection  __jump_table, \"aw\"    \n\t"   \
-        ".align        3                       \n\t"   \
+        ".align        " __stringify(PTRLOG) " \n\t"   \
         ".long         1b - ., " label " - .   \n\t"   \
-        ".quad         " key " - .             \n\t"   \
+        JUMP_LABEL_TYPE  key " - .             \n\t"   \
         ".popsection                           \n\t"
 
 #define ARCH_STATIC_BRANCH_ASM(key, label)             \
index 5bb5a90d26815133e46a9c8ca2f304350acac18e..bfa3fd879c7f33adcf65c6a2703eb6b4eafef7d3 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef _ASM_STRING_H
 #define _ASM_STRING_H
 
+#ifdef CONFIG_64BIT
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *__s, int __c, size_t __count);
 extern void *__memset(void *__s, int __c, size_t __count);
@@ -16,6 +17,7 @@ extern void *__memcpy(void *__to, __const__ void *__from, size_t __n);
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 extern void *__memmove(void *__dest, __const__ void *__src, size_t __n);
+#endif
 
 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
 
index 487be604b96ae5b9d840130809e467a39a5b7fdc..cc929c9fe7e9975b0891864b2a82ff9b8651ddb5 100644 (file)
@@ -27,12 +27,21 @@ static u32 unaligned_instructions_user;
 static u32 unaligned_instructions_kernel;
 #endif
 
-static inline unsigned long read_fpr(unsigned int idx)
+static inline u64 read_fpr(unsigned int idx)
 {
+#ifdef CONFIG_64BIT
 #define READ_FPR(idx, __value)         \
        __asm__ __volatile__("movfr2gr.d %0, $f"#idx"\n\t" : "=r"(__value));
-
-       unsigned long __value;
+#else
+#define READ_FPR(idx, __value)                                                         \
+{                                                                                      \
+       u32 __value_lo, __value_hi;                                                     \
+       __asm__ __volatile__("movfr2gr.s  %0, $f"#idx"\n\t" : "=r"(__value_lo));        \
+       __asm__ __volatile__("movfrh2gr.s %0, $f"#idx"\n\t" : "=r"(__value_hi));        \
+       __value = (__value_lo | ((u64)__value_hi << 32));                               \
+}
+#endif
+       u64 __value;
 
        switch (idx) {
        case 0:
@@ -138,11 +147,20 @@ static inline unsigned long read_fpr(unsigned int idx)
        return __value;
 }
 
-static inline void write_fpr(unsigned int idx, unsigned long value)
+static inline void write_fpr(unsigned int idx, u64 value)
 {
+#ifdef CONFIG_64BIT
 #define WRITE_FPR(idx, value)          \
        __asm__ __volatile__("movgr2fr.d $f"#idx", %0\n\t" :: "r"(value));
-
+#else
+#define WRITE_FPR(idx, value)                                                  \
+{                                                                              \
+       u32 value_lo = value;                                                   \
+       u32 value_hi = value >> 32;                                             \
+       __asm__ __volatile__("movgr2fr.w  $f"#idx", %0\n\t" :: "r"(value_lo));  \
+       __asm__ __volatile__("movgr2frh.w $f"#idx", %0\n\t" :: "r"(value_hi));  \
+}
+#endif
        switch (idx) {
        case 0:
                WRITE_FPR(0, value);
@@ -252,7 +270,7 @@ void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned i
        bool sign, write;
        bool user = user_mode(regs);
        unsigned int res, size = 0;
-       unsigned long value = 0;
+       u64 value = 0;
        union loongarch_instruction insn;
 
        perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
diff --git a/arch/loongarch/lib/bswapdi.c b/arch/loongarch/lib/bswapdi.c
new file mode 100644 (file)
index 0000000..88242dc
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/export.h>
+#include <linux/compiler.h>
+#include <uapi/linux/swab.h>
+
+/* To silence -Wmissing-prototypes. */
+unsigned long long __bswapdi2(unsigned long long u);
+
+unsigned long long notrace __bswapdi2(unsigned long long u)
+{
+       return ___constant_swab64(u);
+}
+EXPORT_SYMBOL(__bswapdi2);
diff --git a/arch/loongarch/lib/bswapsi.c b/arch/loongarch/lib/bswapsi.c
new file mode 100644 (file)
index 0000000..2ed6554
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/export.h>
+#include <linux/compiler.h>
+#include <uapi/linux/swab.h>
+
+/* To silence -Wmissing-prototypes. */
+unsigned int __bswapsi2(unsigned int u);
+
+unsigned int notrace __bswapsi2(unsigned int u)
+{
+       return ___constant_swab32(u);
+}
+EXPORT_SYMBOL(__bswapsi2);
index 185f82d85810afa8766f03f9f9b0268b02625483..470c0bfa3463bf8a6e258b00c07ee784079ac1d1 100644 (file)
  * a3: sign
  */
 SYM_FUNC_START(unaligned_read)
-       beqz    a2, 5f
+       beqz            a2, 5f
 
-       li.w    t2, 0
-       addi.d  t0, a2, -1
-       slli.d  t1, t0, 3
-       add.d   a0, a0, t0
+       li.w            t2, 0
+       LONG_ADDI       t0, a2, -1
+       PTR_SLLI        t1, t0, LONGLOG
+       PTR_ADD         a0, a0, t0
 
-       beqz    a3, 2f
-1:     ld.b    t3, a0, 0
-       b       3f
+       beqz            a3, 2f
+1:     ld.b            t3, a0, 0
+       b               3f
 
-2:     ld.bu   t3, a0, 0
-3:     sll.d   t3, t3, t1
-       or      t2, t2, t3
-       addi.d  t1, t1, -8
-       addi.d  a0, a0, -1
-       addi.d  a2, a2, -1
-       bgtz    a2, 2b
-4:     st.d    t2, a1, 0
+2:     ld.bu           t3, a0, 0
+3:     LONG_SLLV       t3, t3, t1
+       or              t2, t2, t3
+       LONG_ADDI       t1, t1, -8
+       PTR_ADDI        a0, a0, -1
+       PTR_ADDI        a2, a2, -1
+       bgtz            a2, 2b
+4:     LONG_S          t2, a1, 0
 
-       move    a0, a2
-       jr      ra
+       move            a0, a2
+       jr              ra
 
-5:     li.w    a0, -EFAULT
-       jr      ra
+5:     li.w            a0, -EFAULT
+       jr              ra
 
-       _asm_extable 1b, .L_fixup_handle_unaligned
-       _asm_extable 2b, .L_fixup_handle_unaligned
-       _asm_extable 4b, .L_fixup_handle_unaligned
+       _asm_extable    1b, .L_fixup_handle_unaligned
+       _asm_extable    2b, .L_fixup_handle_unaligned
+       _asm_extable    4b, .L_fixup_handle_unaligned
 SYM_FUNC_END(unaligned_read)
 
 /*
@@ -63,21 +63,21 @@ SYM_FUNC_END(unaligned_read)
  * a2: n
  */
 SYM_FUNC_START(unaligned_write)
-       beqz    a2, 3f
+       beqz            a2, 3f
 
-       li.w    t0, 0
-1:     srl.d   t1, a1, t0
-2:     st.b    t1, a0, 0
-       addi.d  t0, t0, 8
-       addi.d  a2, a2, -1
-       addi.d  a0, a0, 1
-       bgtz    a2, 1b
+       li.w            t0, 0
+1:     LONG_SRLV       t1, a1, t0
+2:     st.b            t1, a0, 0
+       LONG_ADDI       t0, t0, 8
+       PTR_ADDI        a2, a2, -1
+       PTR_ADDI        a0, a0, 1
+       bgtz            a2, 1b
 
-       move    a0, a2
-       jr      ra
+       move            a0, a2
+       jr              ra
 
-3:     li.w    a0, -EFAULT
-       jr      ra
+3:     li.w            a0, -EFAULT
+       jr              ra
 
-       _asm_extable 2b, .L_fixup_handle_unaligned
+       _asm_extable    2b, .L_fixup_handle_unaligned
 SYM_FUNC_END(unaligned_write)
index 5bbdb9fd76e5d055f3d51b62ce68cf7af2e88c0f..faa4fe4e7461ce8ce7e43fa179d9953df43de1a8 100644 (file)
@@ -72,10 +72,10 @@ static int __init loongson3_acpi_suspend_init(void)
        status = acpi_evaluate_integer(NULL, "\\SADR", NULL, &suspend_addr);
        if (ACPI_FAILURE(status) || !suspend_addr) {
                pr_info("ACPI S3 supported with hardware register default\n");
-               loongson_sysconf.suspend_addr = (u64)default_suspend_addr;
+               loongson_sysconf.suspend_addr = (unsigned long)default_suspend_addr;
        } else {
                pr_info("ACPI S3 supported with Loongson ACPI SADR extension\n");
-               loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr));
+               loongson_sysconf.suspend_addr = (unsigned long)phys_to_virt(PHYSADDR(suspend_addr));
        }
 #endif
        return 0;
index df0865df26fae545e61c6281aa0bf73ac9284c1a..c8119ad5fb2c8a8d814433c3c10dec86826ded8f 100644 (file)
 
 /* preparatory stuff */
 .macro SETUP_SLEEP
-       addi.d          sp, sp, -PT_SIZE
-       st.d            $r1, sp, PT_R1
-       st.d            $r2, sp, PT_R2
-       st.d            $r3, sp, PT_R3
-       st.d            $r4, sp, PT_R4
-       st.d            $r21, sp, PT_R21
-       st.d            $r22, sp, PT_R22
-       st.d            $r23, sp, PT_R23
-       st.d            $r24, sp, PT_R24
-       st.d            $r25, sp, PT_R25
-       st.d            $r26, sp, PT_R26
-       st.d            $r27, sp, PT_R27
-       st.d            $r28, sp, PT_R28
-       st.d            $r29, sp, PT_R29
-       st.d            $r30, sp, PT_R30
-       st.d            $r31, sp, PT_R31
+       PTR_ADDI        sp, sp, -PT_SIZE
+       REG_S           $r1, sp, PT_R1
+       REG_S           $r2, sp, PT_R2
+       REG_S           $r3, sp, PT_R3
+       REG_S           $r4, sp, PT_R4
+       REG_S           $r21, sp, PT_R21
+       REG_S           $r22, sp, PT_R22
+       REG_S           $r23, sp, PT_R23
+       REG_S           $r24, sp, PT_R24
+       REG_S           $r25, sp, PT_R25
+       REG_S           $r26, sp, PT_R26
+       REG_S           $r27, sp, PT_R27
+       REG_S           $r28, sp, PT_R28
+       REG_S           $r29, sp, PT_R29
+       REG_S           $r30, sp, PT_R30
+       REG_S           $r31, sp, PT_R31
 .endm
 
 .macro SETUP_WAKEUP
-       ld.d            $r1, sp, PT_R1
-       ld.d            $r2, sp, PT_R2
-       ld.d            $r3, sp, PT_R3
-       ld.d            $r4, sp, PT_R4
-       ld.d            $r21, sp, PT_R21
-       ld.d            $r22, sp, PT_R22
-       ld.d            $r23, sp, PT_R23
-       ld.d            $r24, sp, PT_R24
-       ld.d            $r25, sp, PT_R25
-       ld.d            $r26, sp, PT_R26
-       ld.d            $r27, sp, PT_R27
-       ld.d            $r28, sp, PT_R28
-       ld.d            $r29, sp, PT_R29
-       ld.d            $r30, sp, PT_R30
-       ld.d            $r31, sp, PT_R31
-       addi.d          sp, sp, PT_SIZE
+       REG_L           $r1, sp, PT_R1
+       REG_L           $r2, sp, PT_R2
+       REG_L           $r3, sp, PT_R3
+       REG_L           $r4, sp, PT_R4
+       REG_L           $r21, sp, PT_R21
+       REG_L           $r22, sp, PT_R22
+       REG_L           $r23, sp, PT_R23
+       REG_L           $r24, sp, PT_R24
+       REG_L           $r25, sp, PT_R25
+       REG_L           $r26, sp, PT_R26
+       REG_L           $r27, sp, PT_R27
+       REG_L           $r28, sp, PT_R28
+       REG_L           $r29, sp, PT_R29
+       REG_L           $r30, sp, PT_R30
+       REG_L           $r31, sp, PT_R31
+       PTR_ADDI        sp, sp, PT_SIZE
 .endm
 
        .text
@@ -59,15 +59,15 @@ SYM_FUNC_START(loongarch_suspend_enter)
        SETUP_SLEEP
 
        la.pcrel        t0, acpi_saved_sp
-       st.d            sp, t0, 0
+       REG_S           sp, t0, 0
 
        bl              __flush_cache_all
 
        /* Pass RA and SP to BIOS */
-       addi.d          a1, sp, 0
+       PTR_ADDI        a1, sp, 0
        la.pcrel        a0, loongarch_wakeup_start
        la.pcrel        t0, loongarch_suspend_addr
-       ld.d            t0, t0, 0
+       REG_L           t0, t0, 0
        jirl            ra, t0, 0 /* Call BIOS's STR sleep routine */
 
        /*
@@ -83,7 +83,7 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
        csrwr           t0, LOONGARCH_CSR_CRMD
 
        la.pcrel        t0, acpi_saved_sp
-       ld.d            sp, t0, 0
+       REG_L           sp, t0, 0
 
        SETUP_WAKEUP
        jr              ra