From: Huacai Chen Date: Mon, 8 Dec 2025 10:09:17 +0000 (+0800) Subject: LoongArch: Adjust boot & setup for 32BIT/64BIT X-Git-Tag: v6.19-rc1~21^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b2afeafaf9c2d584439fc14fdc1462425b41fd3;p=thirdparty%2Flinux.git LoongArch: Adjust boot & setup for 32BIT/64BIT 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 Signed-off-by: Jiaxun Yang Signed-off-by: Huacai Chen --- diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h index e739dbc6329d..9766a100504a 100644 --- a/arch/loongarch/include/asm/addrspace.h +++ b/arch/loongarch/include/asm/addrspace.h @@ -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. diff --git a/arch/loongarch/include/asm/dmi.h b/arch/loongarch/include/asm/dmi.h index 605493417753..11bb3c8a7179 100644 --- a/arch/loongarch/include/asm/dmi.h +++ b/arch/loongarch/include/asm/dmi.h @@ -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)); } diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h index 4a06856ece3b..3943647503a9 100644 --- a/arch/loongarch/include/asm/irq.h +++ b/arch/loongarch/include/asm/irq.h @@ -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 { diff --git a/arch/loongarch/kernel/efi-header.S b/arch/loongarch/kernel/efi-header.S index ba0bdbf86aa8..6df56241cb95 100644 --- a/arch/loongarch/kernel/efi-header.S +++ b/arch/loongarch/kernel/efi-header.S @@ -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 */ diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 860a3bc030e0..52c21c895318 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -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; diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 23bd5ae2212c..841206fde3ab 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -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); diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index e3865e92a917..aba548db2446 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -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 */ diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c index 76abbb8d2931..82aa3f035927 100644 --- a/arch/loongarch/kernel/relocate.c +++ b/arch/loongarch/kernel/relocate.c @@ -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 } }