]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: Adjust boot & setup 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 boot & setup for both 32BIT and 64BIT, including: efi header
definition, MAX_IO_PICS definition, kernel entry and environment setup
routines, etc.

Add a fallback path in fdt_cpu_clk_init() to avoid 0MHz in /proc/cpuinfo
if there is no valid clock freq from firmware.

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/addrspace.h
arch/loongarch/include/asm/dmi.h
arch/loongarch/include/asm/irq.h
arch/loongarch/kernel/efi-header.S
arch/loongarch/kernel/efi.c
arch/loongarch/kernel/env.c
arch/loongarch/kernel/head.S
arch/loongarch/kernel/relocate.c

index e739dbc6329dce9ce48446729148baaaa790909a..9766a100504a5d2b985ceccfadca8bd03e0eb062 100644 (file)
@@ -42,7 +42,7 @@ extern unsigned long vm_map_base;
 #endif
 
 #define DMW_PABITS     48
-#define TO_PHYS_MASK   ((1ULL << DMW_PABITS) - 1)
+#define TO_PHYS_MASK   ((_ULL(1) << _ULL(DMW_PABITS)) - 1)
 
 /*
  * Memory above this physical address will be considered highmem.
index 605493417753c8b7a2d482a7ac2bb0a2d2eb62b1..11bb3c8a7179f611da42ad9fb70625d94f11c957 100644 (file)
@@ -12,7 +12,7 @@
 #define dmi_early_unmap(x, l)  dmi_unmap(x)
 #define dmi_alloc(l)           memblock_alloc(l, PAGE_SIZE)
 
-static inline void *dmi_remap(u64 phys_addr, unsigned long size)
+static inline void *dmi_remap(phys_addr_t phys_addr, unsigned long size)
 {
        return ((void *)TO_CACHE(phys_addr));
 }
index 4a06856ece3ba3ab062e2db4a2b3e0d253243010..3943647503a958ba61ed67bd9806790775931f92 100644 (file)
@@ -60,7 +60,12 @@ void spurious_interrupt(void);
 #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
 void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
 
+#ifdef CONFIG_32BIT
+#define MAX_IO_PICS 1
+#else
 #define MAX_IO_PICS 8
+#endif
+
 #define NR_IRQS        (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))
 
 struct acpi_vector_group {
index ba0bdbf86aa85687d1213274ce1208646551b2ae..6df56241cb95a72c8cc100930bba83bf8371edcf 100644 (file)
@@ -9,7 +9,11 @@
        .macro  __EFI_PE_HEADER
        .long   IMAGE_NT_SIGNATURE
 .Lcoff_header:
+#ifdef CONFIG_32BIT
+       .short  IMAGE_FILE_MACHINE_LOONGARCH32          /* Machine */
+#else
        .short  IMAGE_FILE_MACHINE_LOONGARCH64          /* Machine */
+#endif
        .short  .Lsection_count                         /* NumberOfSections */
        .long   0                                       /* TimeDateStamp */
        .long   0                                       /* PointerToSymbolTable */
index 860a3bc030e0669280c898bf597a0543eb1e416c..52c21c8953189670154629ccbd9f0aba4159802f 100644 (file)
@@ -115,7 +115,9 @@ void __init efi_init(void)
 
        efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
 
-       set_bit(EFI_64BIT, &efi.flags);
+       if (IS_ENABLED(CONFIG_64BIT))
+               set_bit(EFI_64BIT, &efi.flags);
+
        efi_nr_tables    = efi_systab->nr_tables;
        efi_config_table = (unsigned long)efi_systab->tables;
 
index 23bd5ae2212c267e408c5d050b6c1ec1af2d6483..841206fde3ab72ae694ad4c03c09a8352a80f178 100644 (file)
@@ -72,9 +72,12 @@ static int __init fdt_cpu_clk_init(void)
 
        clk = of_clk_get(np, 0);
        of_node_put(np);
+       cpu_clock_freq = 200 * 1000 * 1000;
 
-       if (IS_ERR(clk))
+       if (IS_ERR(clk)) {
+               pr_warn("No valid CPU clock freq, assume 200MHz.\n");
                return -ENODEV;
+       }
 
        cpu_clock_freq = clk_get_rate(clk);
        clk_put(clk);
index e3865e92a917a7d66d3538cca3774838abf1266b..aba548db244604f0667c5092e97602166c86fe26 100644 (file)
@@ -43,36 +43,29 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize);
 
 SYM_CODE_START(kernel_entry)                   # kernel entry point
 
-       /* Config direct window and set PG */
-       SETUP_DMWINS    t0
+       SETUP_TWINS
+       SETUP_MODES     t0
        JUMP_VIRT_ADDR  t0, t1
-
-       /* Enable PG */
-       li.w            t0, 0xb0                # PLV=0, IE=0, PG=1
-       csrwr           t0, LOONGARCH_CSR_CRMD
-       li.w            t0, 0x04                # PLV=0, PIE=1, PWE=0
-       csrwr           t0, LOONGARCH_CSR_PRMD
-       li.w            t0, 0x00                # FPE=0, SXE=0, ASXE=0, BTE=0
-       csrwr           t0, LOONGARCH_CSR_EUEN
+       SETUP_DMWINS    t0
 
        la.pcrel        t0, __bss_start         # clear .bss
-       st.d            zero, t0, 0
+       LONG_S          zero, t0, 0
        la.pcrel        t1, __bss_stop - LONGSIZE
 1:
-       addi.d          t0, t0, LONGSIZE
-       st.d            zero, t0, 0
+       PTR_ADDI        t0, t0, LONGSIZE
+       LONG_S          zero, t0, 0
        bne             t0, t1, 1b
 
        la.pcrel        t0, fw_arg0
-       st.d            a0, t0, 0               # firmware arguments
+       PTR_S           a0, t0, 0               # firmware arguments
        la.pcrel        t0, fw_arg1
-       st.d            a1, t0, 0
+       PTR_S           a1, t0, 0
        la.pcrel        t0, fw_arg2
-       st.d            a2, t0, 0
+       PTR_S           a2, t0, 0
 
 #ifdef CONFIG_PAGE_SIZE_4KB
-       li.d            t0, 0
-       li.d            t1, CSR_STFILL
+       LONG_LI         t0, 0
+       LONG_LI         t1, CSR_STFILL
        csrxchg         t0, t1, LOONGARCH_CSR_IMPCTL1
 #endif
        /* KSave3 used for percpu base, initialized as 0 */
@@ -98,7 +91,7 @@ SYM_CODE_START(kernel_entry)                  # kernel entry point
 
        /* Jump to the new kernel: new_pc = current_pc + random_offset */
        pcaddi          t0, 0
-       add.d           t0, t0, a0
+       PTR_ADD         t0, t0, a0
        jirl            zero, t0, 0xc
 #endif /* CONFIG_RANDOMIZE_BASE */
 
@@ -121,12 +114,14 @@ SYM_CODE_END(kernel_entry)
  */
 SYM_CODE_START(smpboot_entry)
 
-       SETUP_DMWINS    t0
+       SETUP_TWINS
+       SETUP_MODES     t0
        JUMP_VIRT_ADDR  t0, t1
+       SETUP_DMWINS    t0
 
 #ifdef CONFIG_PAGE_SIZE_4KB
-       li.d            t0, 0
-       li.d            t1, CSR_STFILL
+       LONG_LI         t0, 0
+       LONG_LI         t1, CSR_STFILL
        csrxchg         t0, t1, LOONGARCH_CSR_IMPCTL1
 #endif
        /* Enable PG */
index 76abbb8d2931607874bfd3670f665c5c22802fba..82aa3f0359278e10fad660395f285cf0fc0de553 100644 (file)
@@ -68,18 +68,25 @@ static inline void __init relocate_absolute(long random_offset)
 
        for (p = begin; (void *)p < end; p++) {
                long v = p->symvalue;
-               uint32_t lu12iw, ori, lu32id, lu52id;
+               uint32_t lu12iw, ori;
+#ifdef CONFIG_64BIT
+               uint32_t lu32id, lu52id;
+#endif
                union loongarch_instruction *insn = (void *)p->pc;
 
                lu12iw = (v >> 12) & 0xfffff;
                ori    = v & 0xfff;
+#ifdef CONFIG_64BIT
                lu32id = (v >> 32) & 0xfffff;
                lu52id = v >> 52;
+#endif
 
                insn[0].reg1i20_format.immediate = lu12iw;
                insn[1].reg2i12_format.immediate = ori;
+#ifdef CONFIG_64BIT
                insn[2].reg1i20_format.immediate = lu32id;
                insn[3].reg2i12_format.immediate = lu52id;
+#endif
        }
 }