Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <arnd@arndb.de>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

+43 -27
+1 -1
arch/loongarch/include/asm/addrspace.h
··· 42 42 #endif 43 43 44 44 #define DMW_PABITS 48 45 - #define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1) 45 + #define TO_PHYS_MASK ((_ULL(1) << _ULL(DMW_PABITS)) - 1) 46 46 47 47 /* 48 48 * Memory above this physical address will be considered highmem.
+1 -1
arch/loongarch/include/asm/dmi.h
··· 12 12 #define dmi_early_unmap(x, l) dmi_unmap(x) 13 13 #define dmi_alloc(l) memblock_alloc(l, PAGE_SIZE) 14 14 15 - static inline void *dmi_remap(u64 phys_addr, unsigned long size) 15 + static inline void *dmi_remap(phys_addr_t phys_addr, unsigned long size) 16 16 { 17 17 return ((void *)TO_CACHE(phys_addr)); 18 18 }
+5
arch/loongarch/include/asm/irq.h
··· 60 60 #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace 61 61 void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu); 62 62 63 + #ifdef CONFIG_32BIT 64 + #define MAX_IO_PICS 1 65 + #else 63 66 #define MAX_IO_PICS 8 67 + #endif 68 + 64 69 #define NR_IRQS (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS)) 65 70 66 71 struct acpi_vector_group {
+4
arch/loongarch/kernel/efi-header.S
··· 9 9 .macro __EFI_PE_HEADER 10 10 .long IMAGE_NT_SIGNATURE 11 11 .Lcoff_header: 12 + #ifdef CONFIG_32BIT 13 + .short IMAGE_FILE_MACHINE_LOONGARCH32 /* Machine */ 14 + #else 12 15 .short IMAGE_FILE_MACHINE_LOONGARCH64 /* Machine */ 16 + #endif 13 17 .short .Lsection_count /* NumberOfSections */ 14 18 .long 0 /* TimeDateStamp */ 15 19 .long 0 /* PointerToSymbolTable */
+3 -1
arch/loongarch/kernel/efi.c
··· 115 115 116 116 efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor); 117 117 118 - set_bit(EFI_64BIT, &efi.flags); 118 + if (IS_ENABLED(CONFIG_64BIT)) 119 + set_bit(EFI_64BIT, &efi.flags); 120 + 119 121 efi_nr_tables = efi_systab->nr_tables; 120 122 efi_config_table = (unsigned long)efi_systab->tables; 121 123
+4 -1
arch/loongarch/kernel/env.c
··· 72 72 73 73 clk = of_clk_get(np, 0); 74 74 of_node_put(np); 75 + cpu_clock_freq = 200 * 1000 * 1000; 75 76 76 - if (IS_ERR(clk)) 77 + if (IS_ERR(clk)) { 78 + pr_warn("No valid CPU clock freq, assume 200MHz.\n"); 77 79 return -ENODEV; 80 + } 78 81 79 82 cpu_clock_freq = clk_get_rate(clk); 80 83 clk_put(clk);
+17 -22
arch/loongarch/kernel/head.S
··· 43 43 44 44 SYM_CODE_START(kernel_entry) # kernel entry point 45 45 46 - /* Config direct window and set PG */ 47 - SETUP_DMWINS t0 46 + SETUP_TWINS 47 + SETUP_MODES t0 48 48 JUMP_VIRT_ADDR t0, t1 49 - 50 - /* Enable PG */ 51 - li.w t0, 0xb0 # PLV=0, IE=0, PG=1 52 - csrwr t0, LOONGARCH_CSR_CRMD 53 - li.w t0, 0x04 # PLV=0, PIE=1, PWE=0 54 - csrwr t0, LOONGARCH_CSR_PRMD 55 - li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 56 - csrwr t0, LOONGARCH_CSR_EUEN 49 + SETUP_DMWINS t0 57 50 58 51 la.pcrel t0, __bss_start # clear .bss 59 - st.d zero, t0, 0 52 + LONG_S zero, t0, 0 60 53 la.pcrel t1, __bss_stop - LONGSIZE 61 54 1: 62 - addi.d t0, t0, LONGSIZE 63 - st.d zero, t0, 0 55 + PTR_ADDI t0, t0, LONGSIZE 56 + LONG_S zero, t0, 0 64 57 bne t0, t1, 1b 65 58 66 59 la.pcrel t0, fw_arg0 67 - st.d a0, t0, 0 # firmware arguments 60 + PTR_S a0, t0, 0 # firmware arguments 68 61 la.pcrel t0, fw_arg1 69 - st.d a1, t0, 0 62 + PTR_S a1, t0, 0 70 63 la.pcrel t0, fw_arg2 71 - st.d a2, t0, 0 64 + PTR_S a2, t0, 0 72 65 73 66 #ifdef CONFIG_PAGE_SIZE_4KB 74 - li.d t0, 0 75 - li.d t1, CSR_STFILL 67 + LONG_LI t0, 0 68 + LONG_LI t1, CSR_STFILL 76 69 csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1 77 70 #endif 78 71 /* KSave3 used for percpu base, initialized as 0 */ ··· 91 98 92 99 /* Jump to the new kernel: new_pc = current_pc + random_offset */ 93 100 pcaddi t0, 0 94 - add.d t0, t0, a0 101 + PTR_ADD t0, t0, a0 95 102 jirl zero, t0, 0xc 96 103 #endif /* CONFIG_RANDOMIZE_BASE */ 97 104 ··· 114 121 */ 115 122 SYM_CODE_START(smpboot_entry) 116 123 117 - SETUP_DMWINS t0 124 + SETUP_TWINS 125 + SETUP_MODES t0 118 126 JUMP_VIRT_ADDR t0, t1 127 + SETUP_DMWINS t0 119 128 120 129 #ifdef CONFIG_PAGE_SIZE_4KB 121 - li.d t0, 0 122 - li.d t1, CSR_STFILL 130 + LONG_LI t0, 0 131 + LONG_LI t1, CSR_STFILL 123 132 csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1 124 133 #endif 125 134 /* Enable PG */
+8 -1
arch/loongarch/kernel/relocate.c
··· 68 68 69 69 for (p = begin; (void *)p < end; p++) { 70 70 long v = p->symvalue; 71 - uint32_t lu12iw, ori, lu32id, lu52id; 71 + uint32_t lu12iw, ori; 72 + #ifdef CONFIG_64BIT 73 + uint32_t lu32id, lu52id; 74 + #endif 72 75 union loongarch_instruction *insn = (void *)p->pc; 73 76 74 77 lu12iw = (v >> 12) & 0xfffff; 75 78 ori = v & 0xfff; 79 + #ifdef CONFIG_64BIT 76 80 lu32id = (v >> 32) & 0xfffff; 77 81 lu52id = v >> 52; 82 + #endif 78 83 79 84 insn[0].reg1i20_format.immediate = lu12iw; 80 85 insn[1].reg2i12_format.immediate = ori; 86 + #ifdef CONFIG_64BIT 81 87 insn[2].reg1i20_format.immediate = lu32id; 82 88 insn[3].reg2i12_format.immediate = lu52id; 89 + #endif 83 90 } 84 91 } 85 92